home *** CD-ROM | disk | FTP | other *** search
/ 61.19.244.139 / 61.19.244.139.zip / 61.19.244.139 / cp2013 / Compulsory2013 / Compulsory.Web2013Data / Web2013.Context.tt < prev    next >
Text File  |  2013-06-07  |  26KB  |  735 lines

  1. ∩╗┐<#@ template language="C#" debug="false" hostspecific="true"#>
  2. <#@ include file="EF.Utility.CS.ttinclude"#><#@
  3.  output extension=".cs"#><#
  4.  
  5. const string inputFile = @"Web2013.edmx";
  6. var textTransform = DynamicTextTransformation.Create(this);
  7. var code = new CodeGenerationTools(this);
  8. var ef = new MetadataTools(this);
  9. var typeMapper = new TypeMapper(code, ef, textTransform.Errors);
  10. var loader = new EdmMetadataLoader(textTransform.Host, textTransform.Errors);
  11. var itemCollection = loader.CreateEdmItemCollection(inputFile);
  12. var modelNamespace = loader.GetModelNamespace(inputFile);
  13. var codeStringGenerator = new CodeStringGenerator(code, typeMapper, ef);
  14.  
  15. var container = itemCollection.OfType<EntityContainer>().FirstOrDefault();
  16. if (container == null)
  17. {
  18.     return string.Empty;
  19. }
  20. #>
  21. //------------------------------------------------------------------------------
  22. // <auto-generated>
  23. // <#=GetResourceString("Template_GeneratedCodeCommentLine1")#>
  24. //
  25. // <#=GetResourceString("Template_GeneratedCodeCommentLine2")#>
  26. // <#=GetResourceString("Template_GeneratedCodeCommentLine3")#>
  27. // </auto-generated>
  28. //------------------------------------------------------------------------------
  29.  
  30. <#
  31.  
  32. var codeNamespace = code.VsNamespaceSuggestion();
  33. if (!String.IsNullOrEmpty(codeNamespace))
  34. {
  35. #>
  36. namespace <#=code.EscapeNamespace(codeNamespace)#>
  37. {
  38. <#
  39.     PushIndent("    ");
  40. }
  41.  
  42. #>
  43. using System;
  44. using System.Data.Entity;
  45. using System.Data.Entity.Infrastructure;
  46. <#
  47. if (container.FunctionImports.Any())
  48. {
  49. #>
  50. using System.Data.Objects;
  51. using System.Data.Objects.DataClasses;
  52. using System.Linq;
  53. <#
  54. }
  55. #>
  56.  
  57. <#=Accessibility.ForType(container)#> partial class <#=code.Escape(container)#> : DbContext
  58. {
  59.     public <#=code.Escape(container)#>()
  60.         : base("name=<#=container.Name#>")
  61.     {
  62. <#
  63. if (!loader.IsLazyLoadingEnabled(container))
  64. {
  65. #>
  66.         this.Configuration.LazyLoadingEnabled = false;
  67. <#
  68. }
  69. #>
  70.     }
  71.  
  72.     protected override void OnModelCreating(DbModelBuilder modelBuilder)
  73.     {
  74.         throw new UnintentionalCodeFirstException();
  75.     }
  76.  
  77. <#
  78.     foreach (var entitySet in container.BaseEntitySets.OfType<EntitySet>())
  79.     {
  80. #>
  81.     <#=codeStringGenerator.DbSet(entitySet)#>
  82. <#
  83.     }
  84.  
  85.     foreach (var edmFunction in container.FunctionImports)
  86.     {
  87.         WriteFunctionImport(typeMapper, codeStringGenerator, edmFunction, modelNamespace, includeMergeOption: false);
  88.     }
  89. #>
  90. }
  91. <#
  92.  
  93. if (!String.IsNullOrEmpty(codeNamespace))
  94. {
  95.     PopIndent();
  96. #>
  97. }
  98. <#
  99. }
  100. #>
  101. <#+
  102.  
  103. private void WriteFunctionImport(TypeMapper typeMapper, CodeStringGenerator codeStringGenerator, EdmFunction edmFunction, string modelNamespace, bool includeMergeOption)
  104. {
  105.     if (typeMapper.IsComposable(edmFunction))
  106.     {
  107. #>
  108.  
  109.     [EdmFunction("<#=edmFunction.NamespaceName#>", "<#=edmFunction.Name#>")]
  110.     <#=codeStringGenerator.ComposableFunctionMethod(edmFunction, modelNamespace)#>
  111.     {
  112. <#+
  113.         codeStringGenerator.WriteFunctionParameters(edmFunction, WriteFunctionParameter);
  114. #>
  115.         <#=codeStringGenerator.ComposableCreateQuery(edmFunction, modelNamespace)#>
  116.     }
  117. <#+
  118.     }
  119.     else
  120.     {
  121. #>
  122.  
  123.     <#=codeStringGenerator.FunctionMethod(edmFunction, modelNamespace, includeMergeOption)#>
  124.     {
  125. <#+
  126.         codeStringGenerator.WriteFunctionParameters(edmFunction, WriteFunctionParameter);
  127. #>
  128.         <#=codeStringGenerator.ExecuteFunction(edmFunction, modelNamespace, includeMergeOption)#>
  129.     }
  130. <#+
  131.         if (typeMapper.GenerateMergeOptionFunction(edmFunction, includeMergeOption))
  132.         {
  133.             WriteFunctionImport(typeMapper, codeStringGenerator, edmFunction, modelNamespace, includeMergeOption: true);
  134.         }
  135.     }
  136. }
  137.  
  138. public void WriteFunctionParameter(string name, string isNotNull, string notNullInit, string nullInit)
  139. {
  140. #>
  141.         var <#=name#> = <#=isNotNull#> ?
  142.             <#=notNullInit#> :
  143.             <#=nullInit#>;
  144.  
  145. <#+
  146. }
  147.  
  148. public const string TemplateId = "CSharp_DbContext_Context_EF5";
  149.  
  150. public class CodeStringGenerator
  151. {
  152.     private readonly CodeGenerationTools _code;
  153.     private readonly TypeMapper _typeMapper;
  154.     private readonly MetadataTools _ef;
  155.  
  156.     public CodeStringGenerator(CodeGenerationTools code, TypeMapper typeMapper, MetadataTools ef)
  157.     {
  158.         ArgumentNotNull(code, "code");
  159.         ArgumentNotNull(typeMapper, "typeMapper");
  160.         ArgumentNotNull(ef, "ef");
  161.  
  162.         _code = code;
  163.         _typeMapper = typeMapper;
  164.         _ef = ef;
  165.     }
  166.  
  167.     public string Property(EdmProperty edmProperty)
  168.     {
  169.         return string.Format(
  170.             CultureInfo.InvariantCulture,
  171.             "{0} {1} {2} {{ {3}get; {4}set; }}",
  172.             Accessibility.ForProperty(edmProperty),
  173.             _typeMapper.GetTypeName(edmProperty.TypeUsage),
  174.             _code.Escape(edmProperty),
  175.             _code.SpaceAfter(Accessibility.ForGetter(edmProperty)),
  176.             _code.SpaceAfter(Accessibility.ForSetter(edmProperty)));
  177.     }
  178.  
  179.     public string NavigationProperty(NavigationProperty navigationProperty)
  180.     {
  181.         var endType = _typeMapper.GetTypeName(navigationProperty.ToEndMember.GetEntityType());
  182.         return string.Format(
  183.             CultureInfo.InvariantCulture,
  184.             "{0} {1} {2} {{ {3}get; {4}set; }}",
  185.             AccessibilityAndVirtual(Accessibility.ForProperty(navigationProperty)),
  186.             navigationProperty.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many ? ("ICollection<" + endType + ">") : endType,
  187.             _code.Escape(navigationProperty),
  188.             _code.SpaceAfter(Accessibility.ForGetter(navigationProperty)),
  189.             _code.SpaceAfter(Accessibility.ForSetter(navigationProperty)));
  190.     }
  191.     
  192.     public string AccessibilityAndVirtual(string accessibility)
  193.     {
  194.         return accessibility + (accessibility != "private" ? " virtual" : "");
  195.     }
  196.     
  197.     public string EntityClassOpening(EntityType entity)
  198.     {
  199.         return string.Format(
  200.             CultureInfo.InvariantCulture,
  201.             "{0} {1}partial class {2}{3}",
  202.             Accessibility.ForType(entity),
  203.             _code.SpaceAfter(_code.AbstractOption(entity)),
  204.             _code.Escape(entity),
  205.             _code.StringBefore(" : ", _typeMapper.GetTypeName(entity.BaseType)));
  206.     }
  207.     
  208.     public string EnumOpening(SimpleType enumType)
  209.     {
  210.         return string.Format(
  211.             CultureInfo.InvariantCulture,
  212.             "{0} enum {1} : {2}",
  213.             Accessibility.ForType(enumType),
  214.             _code.Escape(enumType),
  215.             _code.Escape(_typeMapper.UnderlyingClrType(enumType)));
  216.         }
  217.     
  218.     public void WriteFunctionParameters(EdmFunction edmFunction, Action<string, string, string, string> writeParameter)
  219.     {
  220.         var parameters = FunctionImportParameter.Create(edmFunction.Parameters, _code, _ef);
  221.         foreach (var parameter in parameters.Where(p => p.NeedsLocalVariable))
  222.         {
  223.             var isNotNull = parameter.IsNullableOfT ? parameter.FunctionParameterName + ".HasValue" : parameter.FunctionParameterName + " != null";
  224.             var notNullInit = "new ObjectParameter(\"" + parameter.EsqlParameterName + "\", " + parameter.FunctionParameterName + ")";
  225.             var nullInit = "new ObjectParameter(\"" + parameter.EsqlParameterName + "\", typeof(" + parameter.RawClrTypeName + "))";
  226.             writeParameter(parameter.LocalVariableName, isNotNull, notNullInit, nullInit);
  227.         }
  228.     }
  229.     
  230.     public string ComposableFunctionMethod(EdmFunction edmFunction, string modelNamespace)
  231.     {
  232.         var parameters = _typeMapper.GetParameters(edmFunction);
  233.         
  234.         return string.Format(
  235.             CultureInfo.InvariantCulture,
  236.             "{0} IQueryable<{1}> {2}({3})",
  237.             AccessibilityAndVirtual(Accessibility.ForMethod(edmFunction)),
  238.             _typeMapper.GetTypeName(_typeMapper.GetReturnType(edmFunction), modelNamespace),
  239.             _code.Escape(edmFunction),
  240.             string.Join(", ", parameters.Select(p => p.FunctionParameterType + " " + p.FunctionParameterName).ToArray()));
  241.     }
  242.     
  243.     public string ComposableCreateQuery(EdmFunction edmFunction, string modelNamespace)
  244.     {
  245.         var parameters = _typeMapper.GetParameters(edmFunction);
  246.         
  247.         return string.Format(
  248.             CultureInfo.InvariantCulture,
  249.             "return ((IObjectContextAdapter)this).ObjectContext.CreateQuery<{0}>(\"[{1}].[{2}]({3})\"{4});",
  250.             _typeMapper.GetTypeName(_typeMapper.GetReturnType(edmFunction), modelNamespace),
  251.             edmFunction.NamespaceName,
  252.             edmFunction.Name,
  253.             string.Join(", ", parameters.Select(p => "@" + p.EsqlParameterName).ToArray()),
  254.             _code.StringBefore(", ", string.Join(", ", parameters.Select(p => p.ExecuteParameterName).ToArray())));
  255.     }
  256.     
  257.     public string FunctionMethod(EdmFunction edmFunction, string modelNamespace, bool includeMergeOption)
  258.     {
  259.         var parameters = _typeMapper.GetParameters(edmFunction);
  260.         var returnType = _typeMapper.GetReturnType(edmFunction);
  261.  
  262.         var paramList = String.Join(", ", parameters.Select(p => p.FunctionParameterType + " " + p.FunctionParameterName).ToArray());
  263.         if (includeMergeOption)
  264.         {
  265.             paramList = _code.StringAfter(paramList, ", ") + "MergeOption mergeOption";
  266.         }
  267.  
  268.         return string.Format(
  269.             CultureInfo.InvariantCulture,
  270.             "{0} {1} {2}({3})",
  271.             AccessibilityAndVirtual(Accessibility.ForMethod(edmFunction)),
  272.             returnType == null ? "int" : "ObjectResult<" + _typeMapper.GetTypeName(returnType, modelNamespace) + ">",
  273.             _code.Escape(edmFunction),
  274.             paramList);
  275.     }
  276.     
  277.     public string ExecuteFunction(EdmFunction edmFunction, string modelNamespace, bool includeMergeOption)
  278.     {
  279.         var parameters = _typeMapper.GetParameters(edmFunction);
  280.         var returnType = _typeMapper.GetReturnType(edmFunction);
  281.  
  282.         var callParams = _code.StringBefore(", ", String.Join(", ", parameters.Select(p => p.ExecuteParameterName).ToArray()));
  283.         if (includeMergeOption)
  284.         {
  285.             callParams = ", mergeOption" + callParams;
  286.         }
  287.         
  288.         return string.Format(
  289.             CultureInfo.InvariantCulture,
  290.             "return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction{0}(\"{1}\"{2});",
  291.             returnType == null ? "" : "<" + _typeMapper.GetTypeName(returnType, modelNamespace) + ">",
  292.             edmFunction.Name,
  293.             callParams);
  294.     }
  295.     
  296.     public string DbSet(EntitySet entitySet)
  297.     {
  298.         return string.Format(
  299.             CultureInfo.InvariantCulture,
  300.             "{0} DbSet<{1}> {2} {{ get; set; }}",
  301.             Accessibility.ForReadOnlyProperty(entitySet),
  302.             _typeMapper.GetTypeName(entitySet.ElementType),
  303.             _code.Escape(entitySet));
  304.     }
  305.  
  306.     public string UsingDirectives(bool inHeader, bool includeCollections = true)
  307.     {
  308.         return inHeader == string.IsNullOrEmpty(_code.VsNamespaceSuggestion())
  309.             ? string.Format(
  310.                 CultureInfo.InvariantCulture,
  311.                 "{0}using System;{1}" +
  312.                 "{2}",
  313.                 inHeader ? Environment.NewLine : "",
  314.                 includeCollections ? (Environment.NewLine + "using System.Collections.Generic;") : "",
  315.                 inHeader ? "" : Environment.NewLine)
  316.             : "";
  317.     }
  318. }
  319.  
  320. public class TypeMapper
  321. {
  322.     private const string ExternalTypeNameAttributeName = @"http://schemas.microsoft.com/ado/2006/04/codegeneration:ExternalTypeName";
  323.  
  324.     private readonly System.Collections.IList _errors;
  325.     private readonly CodeGenerationTools _code;
  326.     private readonly MetadataTools _ef;
  327.  
  328.     public TypeMapper(CodeGenerationTools code, MetadataTools ef, System.Collections.IList errors)
  329.     {
  330.         ArgumentNotNull(code, "code");
  331.         ArgumentNotNull(ef, "ef");
  332.         ArgumentNotNull(errors, "errors");
  333.  
  334.         _code = code;
  335.         _ef = ef;
  336.         _errors = errors;
  337.     }
  338.  
  339.     public string GetTypeName(TypeUsage typeUsage)
  340.     {
  341.         return typeUsage == null ? null : GetTypeName(typeUsage.EdmType, _ef.IsNullable(typeUsage), modelNamespace: null);
  342.     }
  343.  
  344.     public string GetTypeName(EdmType edmType)
  345.     {
  346.         return GetTypeName(edmType, isNullable: null, modelNamespace: null);
  347.     }
  348.  
  349.     public string GetTypeName(TypeUsage typeUsage, string modelNamespace)
  350.     {
  351.         return typeUsage == null ? null : GetTypeName(typeUsage.EdmType, _ef.IsNullable(typeUsage), modelNamespace);
  352.     }
  353.  
  354.     public string GetTypeName(EdmType edmType, string modelNamespace)
  355.     {
  356.         return GetTypeName(edmType, isNullable: null, modelNamespace: modelNamespace);
  357.     }
  358.  
  359.     public string GetTypeName(EdmType edmType, bool? isNullable, string modelNamespace)
  360.     {
  361.         if (edmType == null)
  362.         {
  363.             return null;
  364.         }
  365.  
  366.         var collectionType = edmType as CollectionType;
  367.         if (collectionType != null)
  368.         {
  369.             return String.Format(CultureInfo.InvariantCulture, "ICollection<{0}>", GetTypeName(collectionType.TypeUsage, modelNamespace));
  370.         }
  371.  
  372.         var typeName = _code.Escape(edmType.MetadataProperties
  373.                                 .Where(p => p.Name == ExternalTypeNameAttributeName)
  374.                                 .Select(p => (string)p.Value)
  375.                                 .FirstOrDefault())
  376.             ?? (modelNamespace != null && edmType.NamespaceName != modelNamespace ?
  377.                 _code.CreateFullName(_code.EscapeNamespace(edmType.NamespaceName), _code.Escape(edmType)) :
  378.                 _code.Escape(edmType));
  379.  
  380.         if (edmType is StructuralType)
  381.         {
  382.             return typeName;
  383.         }
  384.  
  385.         if (edmType is SimpleType)
  386.         {
  387.             var clrType = UnderlyingClrType(edmType);
  388.             if (!IsEnumType(edmType))
  389.             {
  390.                 typeName = _code.Escape(clrType);
  391.             }
  392.  
  393.             return clrType.IsValueType && isNullable == true ?
  394.                 String.Format(CultureInfo.InvariantCulture, "Nullable<{0}>", typeName) :
  395.                 typeName;
  396.         }
  397.  
  398.         throw new ArgumentException("edmType");
  399.     }
  400.     
  401.     public Type UnderlyingClrType(EdmType edmType)
  402.     {
  403.         ArgumentNotNull(edmType, "edmType");
  404.  
  405.         var primitiveType = edmType as PrimitiveType;
  406.         if (primitiveType != null)
  407.         {
  408.             return primitiveType.ClrEquivalentType;
  409.         }
  410.  
  411.         if (IsEnumType(edmType))
  412.         {
  413.             return GetEnumUnderlyingType(edmType).ClrEquivalentType;
  414.         }
  415.  
  416.         return typeof(object);
  417.     }
  418.     
  419.     public object GetEnumMemberValue(MetadataItem enumMember)
  420.     {
  421.         ArgumentNotNull(enumMember, "enumMember");
  422.         
  423.         var valueProperty = enumMember.GetType().GetProperty("Value");
  424.         return valueProperty == null ? null : valueProperty.GetValue(enumMember, null);
  425.     }
  426.     
  427.     public string GetEnumMemberName(MetadataItem enumMember)
  428.     {
  429.         ArgumentNotNull(enumMember, "enumMember");
  430.         
  431.         var nameProperty = enumMember.GetType().GetProperty("Name");
  432.         return nameProperty == null ? null : (string)nameProperty.GetValue(enumMember, null);
  433.     }
  434.  
  435.     public System.Collections.IEnumerable GetEnumMembers(EdmType enumType)
  436.     {
  437.         ArgumentNotNull(enumType, "enumType");
  438.  
  439.         var membersProperty = enumType.GetType().GetProperty("Members");
  440.         return membersProperty != null 
  441.             ? (System.Collections.IEnumerable)membersProperty.GetValue(enumType, null)
  442.             : Enumerable.Empty<MetadataItem>();
  443.     }
  444.     
  445.     public bool EnumIsFlags(EdmType enumType)
  446.     {
  447.         ArgumentNotNull(enumType, "enumType");
  448.         
  449.         var isFlagsProperty = enumType.GetType().GetProperty("IsFlags");
  450.         return isFlagsProperty != null && (bool)isFlagsProperty.GetValue(enumType, null);
  451.     }
  452.  
  453.     public bool IsEnumType(GlobalItem edmType)
  454.     {
  455.         ArgumentNotNull(edmType, "edmType");
  456.  
  457.         return edmType.GetType().Name == "EnumType";
  458.     }
  459.  
  460.     public PrimitiveType GetEnumUnderlyingType(EdmType enumType)
  461.     {
  462.         ArgumentNotNull(enumType, "enumType");
  463.  
  464.         return (PrimitiveType)enumType.GetType().GetProperty("UnderlyingType").GetValue(enumType, null);
  465.     }
  466.  
  467.     public string CreateLiteral(object value)
  468.     {
  469.         if (value == null || value.GetType() != typeof(TimeSpan))
  470.         {
  471.             return _code.CreateLiteral(value);
  472.         }
  473.  
  474.         return string.Format(CultureInfo.InvariantCulture, "new TimeSpan({0})", ((TimeSpan)value).Ticks);
  475.     }
  476.     
  477.     public bool VerifyCaseInsensitiveTypeUniqueness(IEnumerable<string> types, string sourceFile)
  478.     {
  479.         ArgumentNotNull(types, "types");
  480.         ArgumentNotNull(sourceFile, "sourceFile");
  481.         
  482.         var hash = new HashSet<string>(StringComparer.InvariantCultureIgnoreCase);
  483.         if (types.Any(item => !hash.Add(item)))
  484.         {
  485.             _errors.Add(
  486.                 new CompilerError(sourceFile, -1, -1, "6023",
  487.                     String.Format(CultureInfo.CurrentCulture, GetResourceString("Template_CaseInsensitiveTypeConflict"))));
  488.             return false;
  489.         }
  490.         return true;
  491.     }
  492.     
  493.     public IEnumerable<SimpleType> GetEnumItemsToGenerate(IEnumerable<GlobalItem> itemCollection)
  494.     {
  495.         return GetItemsToGenerate<SimpleType>(itemCollection)
  496.             .Where(e => IsEnumType(e));
  497.     }
  498.     
  499.     public IEnumerable<T> GetItemsToGenerate<T>(IEnumerable<GlobalItem> itemCollection) where T: EdmType
  500.     {
  501.         return itemCollection
  502.             .OfType<T>()
  503.             .Where(i => !i.MetadataProperties.Any(p => p.Name == ExternalTypeNameAttributeName))
  504.             .OrderBy(i => i.Name);
  505.     }
  506.  
  507.     public IEnumerable<string> GetAllGlobalItems(IEnumerable<GlobalItem> itemCollection)
  508.     {
  509.         return itemCollection
  510.             .Where(i => i is EntityType || i is ComplexType || i is EntityContainer || IsEnumType(i))
  511.             .Select(g => GetGlobalItemName(g));
  512.     }
  513.  
  514.     public string GetGlobalItemName(GlobalItem item)
  515.     {
  516.         if (item is EdmType)
  517.         {
  518.             return ((EdmType)item).Name;
  519.         }
  520.         else
  521.         {
  522.             return ((EntityContainer)item).Name;
  523.         }
  524.     }
  525.  
  526.     public IEnumerable<EdmProperty> GetSimpleProperties(EntityType type)
  527.     {
  528.         return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type);
  529.     }
  530.     
  531.     public IEnumerable<EdmProperty> GetSimpleProperties(ComplexType type)
  532.     {
  533.         return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type);
  534.     }
  535.     
  536.     public IEnumerable<EdmProperty> GetComplexProperties(EntityType type)
  537.     {
  538.         return type.Properties.Where(p => p.TypeUsage.EdmType is ComplexType && p.DeclaringType == type);
  539.     }
  540.     
  541.     public IEnumerable<EdmProperty> GetComplexProperties(ComplexType type)
  542.     {
  543.         return type.Properties.Where(p => p.TypeUsage.EdmType is ComplexType && p.DeclaringType == type);
  544.     }
  545.  
  546.     public IEnumerable<EdmProperty> GetPropertiesWithDefaultValues(EntityType type)
  547.     {
  548.         return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type && p.DefaultValue != null);
  549.     }
  550.     
  551.     public IEnumerable<EdmProperty> GetPropertiesWithDefaultValues(ComplexType type)
  552.     {
  553.         return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type && p.DefaultValue != null);
  554.     }
  555.  
  556.     public IEnumerable<NavigationProperty> GetNavigationProperties(EntityType type)
  557.     {
  558.         return type.NavigationProperties.Where(np => np.DeclaringType == type);
  559.     }
  560.     
  561.     public IEnumerable<NavigationProperty> GetCollectionNavigationProperties(EntityType type)
  562.     {
  563.         return type.NavigationProperties.Where(np => np.DeclaringType == type && np.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many);
  564.     }
  565.     
  566.     public FunctionParameter GetReturnParameter(EdmFunction edmFunction)
  567.     {
  568.         ArgumentNotNull(edmFunction, "edmFunction");
  569.  
  570.         var returnParamsProperty = edmFunction.GetType().GetProperty("ReturnParameters");
  571.         return returnParamsProperty == null
  572.             ? edmFunction.ReturnParameter
  573.             : ((IEnumerable<FunctionParameter>)returnParamsProperty.GetValue(edmFunction, null)).FirstOrDefault();
  574.     }
  575.  
  576.     public bool IsComposable(EdmFunction edmFunction)
  577.     {
  578.         ArgumentNotNull(edmFunction, "edmFunction");
  579.  
  580.         var isComposableProperty = edmFunction.GetType().GetProperty("IsComposableAttribute");
  581.         return isComposableProperty != null && (bool)isComposableProperty.GetValue(edmFunction, null);
  582.     }
  583.  
  584.     public IEnumerable<FunctionImportParameter> GetParameters(EdmFunction edmFunction)
  585.     {
  586.         return FunctionImportParameter.Create(edmFunction.Parameters, _code, _ef);
  587.     }
  588.  
  589.     public TypeUsage GetReturnType(EdmFunction edmFunction)
  590.     {
  591.         var returnParam = GetReturnParameter(edmFunction);
  592.         return returnParam == null ? null : _ef.GetElementType(returnParam.TypeUsage);
  593.     }
  594.     
  595.     public bool GenerateMergeOptionFunction(EdmFunction edmFunction, bool includeMergeOption)
  596.     {
  597.         var returnType = GetReturnType(edmFunction);
  598.         return !includeMergeOption && returnType != null && returnType.EdmType.BuiltInTypeKind == BuiltInTypeKind.EntityType;
  599.     }
  600. }
  601.  
  602. public class EdmMetadataLoader
  603. {
  604.     private readonly IDynamicHost _host;
  605.     private readonly System.Collections.IList _errors;
  606.  
  607.     public EdmMetadataLoader(IDynamicHost host, System.Collections.IList errors)
  608.     {
  609.         ArgumentNotNull(host, "host");
  610.         ArgumentNotNull(errors, "errors");
  611.  
  612.         _host = host;
  613.         _errors = errors;
  614.     }
  615.  
  616.     public IEnumerable<GlobalItem> CreateEdmItemCollection(string sourcePath)
  617.     {
  618.         ArgumentNotNull(sourcePath, "sourcePath");
  619.  
  620.         if (!ValidateInputPath(sourcePath))
  621.         {
  622.             return new EdmItemCollection();
  623.         }
  624.  
  625.         var schemaElement = LoadRootElement(_host.ResolvePath(sourcePath));
  626.         if (schemaElement != null)
  627.         {
  628.             using (var reader = schemaElement.CreateReader())
  629.             {
  630.                 IList<EdmSchemaError> errors;
  631.                 var itemCollection = MetadataItemCollectionFactory.CreateEdmItemCollection(new[] { reader }, out errors);
  632.  
  633.                 ProcessErrors(errors, sourcePath);
  634.  
  635.                 return itemCollection;
  636.             }
  637.         }
  638.         return new EdmItemCollection();
  639.     }
  640.  
  641.     public string GetModelNamespace(string sourcePath)
  642.     {
  643.         ArgumentNotNull(sourcePath, "sourcePath");
  644.  
  645.         if (!ValidateInputPath(sourcePath))
  646.         {
  647.             return string.Empty;
  648.         }
  649.  
  650.         var model = LoadRootElement(_host.ResolvePath(sourcePath));
  651.         if (model == null)
  652.         {
  653.             return string.Empty;
  654.         }
  655.  
  656.         var attribute = model.Attribute("Namespace");
  657.         return attribute != null ? attribute.Value : "";
  658.     }
  659.  
  660.     private bool ValidateInputPath(string sourcePath)
  661.     {
  662.         if (sourcePath == "$" + "edmxInputFile" + "$")
  663.         {
  664.             _errors.Add(
  665.                 new CompilerError(_host.TemplateFile ?? sourcePath, 0, 0, string.Empty,
  666.                     GetResourceString("Template_ReplaceVsItemTemplateToken")));
  667.             return false;
  668.         }
  669.  
  670.         return true;
  671.     }
  672.  
  673.     public XElement LoadRootElement(string sourcePath)
  674.     {
  675.         ArgumentNotNull(sourcePath, "sourcePath");
  676.  
  677.         var root = XElement.Load(sourcePath, LoadOptions.SetBaseUri | LoadOptions.SetLineInfo);
  678.         return root.Elements()
  679.             .Where(e => e.Name.LocalName == "Runtime")
  680.             .Elements()
  681.             .Where(e => e.Name.LocalName == "ConceptualModels")
  682.             .Elements()
  683.             .Where(e => e.Name.LocalName == "Schema")
  684.             .FirstOrDefault()
  685.                 ?? root;
  686.     }
  687.  
  688.     private void ProcessErrors(IEnumerable<EdmSchemaError> errors, string sourceFilePath)
  689.     {
  690.         foreach (var error in errors)
  691.         {
  692.             _errors.Add(
  693.                 new CompilerError(
  694.                     error.SchemaLocation ?? sourceFilePath,
  695.                     error.Line,
  696.                     error.Column,
  697.                     error.ErrorCode.ToString(CultureInfo.InvariantCulture),
  698.                     error.Message)
  699.                 {
  700.                     IsWarning = error.Severity == EdmSchemaErrorSeverity.Warning
  701.                 });
  702.         }
  703.     }
  704.     
  705.     public bool IsLazyLoadingEnabled(EntityContainer container)
  706.     {
  707.         string lazyLoadingAttributeValue;
  708.         var lazyLoadingAttributeName = MetadataConstants.EDM_ANNOTATION_09_02 + ":LazyLoadingEnabled";
  709.         bool isLazyLoading;
  710.         return !MetadataTools.TryGetStringMetadataPropertySetting(container, lazyLoadingAttributeName, out lazyLoadingAttributeValue)
  711.             || !bool.TryParse(lazyLoadingAttributeValue, out isLazyLoading)
  712.             || isLazyLoading;
  713.     }
  714. }
  715.  
  716. public static void ArgumentNotNull<T>(T arg, string name) where T : class
  717. {
  718.     if (arg == null)
  719.     {
  720.         throw new ArgumentNullException(name);
  721.     }
  722. }
  723.     
  724. private static readonly Lazy<System.Resources.ResourceManager> ResourceManager =
  725.     new Lazy<System.Resources.ResourceManager>(
  726.         () => new System.Resources.ResourceManager("System.Data.Entity.Design", typeof(MetadataItemCollectionFactory).Assembly), isThreadSafe: true);
  727.  
  728. public static string GetResourceString(string resourceName)
  729. {
  730.     ArgumentNotNull(resourceName, "resourceName");
  731.  
  732.     return ResourceManager.Value.GetString(resourceName, null);
  733. }
  734.  
  735. #>