Models.tt 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733
  1. <#@ template language="C#" debug="false" hostspecific="true"#>
  2. <#@ include file="EF6.Utility.CS.ttinclude"#><#@
  3. output extension=".cs"#><#
  4. const string inputFile = @"Models.edmx";
  5. var textTransform = DynamicTextTransformation.Create(this);
  6. var code = new CodeGenerationTools(this);
  7. var ef = new MetadataTools(this);
  8. var typeMapper = new TypeMapper(code, ef, textTransform.Errors);
  9. var fileManager = EntityFrameworkTemplateFileManager.Create(this);
  10. var itemCollection = new EdmMetadataLoader(textTransform.Host, textTransform.Errors).CreateEdmItemCollection(inputFile);
  11. var codeStringGenerator = new CodeStringGenerator(code, typeMapper, ef);
  12. if (!typeMapper.VerifyCaseInsensitiveTypeUniqueness(typeMapper.GetAllGlobalItems(itemCollection), inputFile))
  13. {
  14. return string.Empty;
  15. }
  16. WriteHeader(codeStringGenerator, fileManager);
  17. foreach (var entity in typeMapper.GetItemsToGenerate<EntityType>(itemCollection))
  18. {
  19. fileManager.StartNewFile(entity.Name + ".cs");
  20. BeginNamespace(code);
  21. #>
  22. <#=codeStringGenerator.UsingDirectives(inHeader: false)#>
  23. <#=codeStringGenerator.EntityClassOpening(entity)#>
  24. {
  25. <#
  26. var propertiesWithDefaultValues = typeMapper.GetPropertiesWithDefaultValues(entity);
  27. var collectionNavigationProperties = typeMapper.GetCollectionNavigationProperties(entity);
  28. var complexProperties = typeMapper.GetComplexProperties(entity);
  29. if (propertiesWithDefaultValues.Any() || collectionNavigationProperties.Any() || complexProperties.Any())
  30. {
  31. #>
  32. [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
  33. public <#=code.Escape(entity)#>()
  34. {
  35. <#
  36. foreach (var edmProperty in propertiesWithDefaultValues)
  37. {
  38. #>
  39. this.<#=code.Escape(edmProperty)#> = <#=typeMapper.CreateLiteral(edmProperty.DefaultValue)#>;
  40. <#
  41. }
  42. foreach (var navigationProperty in collectionNavigationProperties)
  43. {
  44. #>
  45. this.<#=code.Escape(navigationProperty)#> = new HashSet<<#=typeMapper.GetTypeName(navigationProperty.ToEndMember.GetEntityType())#>>();
  46. <#
  47. }
  48. foreach (var complexProperty in complexProperties)
  49. {
  50. #>
  51. this.<#=code.Escape(complexProperty)#> = new <#=typeMapper.GetTypeName(complexProperty.TypeUsage)#>();
  52. <#
  53. }
  54. #>
  55. }
  56. <#
  57. }
  58. var simpleProperties = typeMapper.GetSimpleProperties(entity);
  59. if (simpleProperties.Any())
  60. {
  61. foreach (var edmProperty in simpleProperties)
  62. {
  63. #>
  64. <#=codeStringGenerator.Property(edmProperty)#>
  65. <#
  66. }
  67. }
  68. if (complexProperties.Any())
  69. {
  70. #>
  71. <#
  72. foreach(var complexProperty in complexProperties)
  73. {
  74. #>
  75. <#=codeStringGenerator.Property(complexProperty)#>
  76. <#
  77. }
  78. }
  79. var navigationProperties = typeMapper.GetNavigationProperties(entity);
  80. if (navigationProperties.Any())
  81. {
  82. #>
  83. <#
  84. foreach (var navigationProperty in navigationProperties)
  85. {
  86. if (navigationProperty.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many)
  87. {
  88. #>
  89. [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
  90. <#
  91. }
  92. #>
  93. <#=codeStringGenerator.NavigationProperty(navigationProperty)#>
  94. <#
  95. }
  96. }
  97. #>
  98. }
  99. <#
  100. EndNamespace(code);
  101. }
  102. foreach (var complex in typeMapper.GetItemsToGenerate<ComplexType>(itemCollection))
  103. {
  104. fileManager.StartNewFile(complex.Name + ".cs");
  105. BeginNamespace(code);
  106. #>
  107. <#=codeStringGenerator.UsingDirectives(inHeader: false, includeCollections: false)#>
  108. <#=Accessibility.ForType(complex)#> partial class <#=code.Escape(complex)#>
  109. {
  110. <#
  111. var complexProperties = typeMapper.GetComplexProperties(complex);
  112. var propertiesWithDefaultValues = typeMapper.GetPropertiesWithDefaultValues(complex);
  113. if (propertiesWithDefaultValues.Any() || complexProperties.Any())
  114. {
  115. #>
  116. public <#=code.Escape(complex)#>()
  117. {
  118. <#
  119. foreach (var edmProperty in propertiesWithDefaultValues)
  120. {
  121. #>
  122. this.<#=code.Escape(edmProperty)#> = <#=typeMapper.CreateLiteral(edmProperty.DefaultValue)#>;
  123. <#
  124. }
  125. foreach (var complexProperty in complexProperties)
  126. {
  127. #>
  128. this.<#=code.Escape(complexProperty)#> = new <#=typeMapper.GetTypeName(complexProperty.TypeUsage)#>();
  129. <#
  130. }
  131. #>
  132. }
  133. <#
  134. }
  135. var simpleProperties = typeMapper.GetSimpleProperties(complex);
  136. if (simpleProperties.Any())
  137. {
  138. foreach(var edmProperty in simpleProperties)
  139. {
  140. #>
  141. <#=codeStringGenerator.Property(edmProperty)#>
  142. <#
  143. }
  144. }
  145. if (complexProperties.Any())
  146. {
  147. #>
  148. <#
  149. foreach(var edmProperty in complexProperties)
  150. {
  151. #>
  152. <#=codeStringGenerator.Property(edmProperty)#>
  153. <#
  154. }
  155. }
  156. #>
  157. }
  158. <#
  159. EndNamespace(code);
  160. }
  161. foreach (var enumType in typeMapper.GetEnumItemsToGenerate(itemCollection))
  162. {
  163. fileManager.StartNewFile(enumType.Name + ".cs");
  164. BeginNamespace(code);
  165. #>
  166. <#=codeStringGenerator.UsingDirectives(inHeader: false, includeCollections: false)#>
  167. <#
  168. if (typeMapper.EnumIsFlags(enumType))
  169. {
  170. #>
  171. [Flags]
  172. <#
  173. }
  174. #>
  175. <#=codeStringGenerator.EnumOpening(enumType)#>
  176. {
  177. <#
  178. var foundOne = false;
  179. foreach (MetadataItem member in typeMapper.GetEnumMembers(enumType))
  180. {
  181. foundOne = true;
  182. #>
  183. <#=code.Escape(typeMapper.GetEnumMemberName(member))#> = <#=typeMapper.GetEnumMemberValue(member)#>,
  184. <#
  185. }
  186. if (foundOne)
  187. {
  188. this.GenerationEnvironment.Remove(this.GenerationEnvironment.Length - 3, 1);
  189. }
  190. #>
  191. }
  192. <#
  193. EndNamespace(code);
  194. }
  195. fileManager.Process();
  196. #>
  197. <#+
  198. public void WriteHeader(CodeStringGenerator codeStringGenerator, EntityFrameworkTemplateFileManager fileManager)
  199. {
  200. fileManager.StartHeader();
  201. #>
  202. //------------------------------------------------------------------------------
  203. // <auto-generated>
  204. // <#=CodeGenerationTools.GetResourceString("Template_GeneratedCodeCommentLine1")#>
  205. //
  206. // <#=CodeGenerationTools.GetResourceString("Template_GeneratedCodeCommentLine2")#>
  207. // <#=CodeGenerationTools.GetResourceString("Template_GeneratedCodeCommentLine3")#>
  208. // </auto-generated>
  209. //------------------------------------------------------------------------------
  210. <#=codeStringGenerator.UsingDirectives(inHeader: true)#>
  211. <#+
  212. fileManager.EndBlock();
  213. }
  214. public void BeginNamespace(CodeGenerationTools code)
  215. {
  216. var codeNamespace = code.VsNamespaceSuggestion();
  217. if (!String.IsNullOrEmpty(codeNamespace))
  218. {
  219. #>
  220. namespace <#=code.EscapeNamespace(codeNamespace)#>
  221. {
  222. <#+
  223. PushIndent(" ");
  224. }
  225. }
  226. public void EndNamespace(CodeGenerationTools code)
  227. {
  228. if (!String.IsNullOrEmpty(code.VsNamespaceSuggestion()))
  229. {
  230. PopIndent();
  231. #>
  232. }
  233. <#+
  234. }
  235. }
  236. public const string TemplateId = "CSharp_DbContext_Types_EF6";
  237. public class CodeStringGenerator
  238. {
  239. private readonly CodeGenerationTools _code;
  240. private readonly TypeMapper _typeMapper;
  241. private readonly MetadataTools _ef;
  242. public CodeStringGenerator(CodeGenerationTools code, TypeMapper typeMapper, MetadataTools ef)
  243. {
  244. ArgumentNotNull(code, "code");
  245. ArgumentNotNull(typeMapper, "typeMapper");
  246. ArgumentNotNull(ef, "ef");
  247. _code = code;
  248. _typeMapper = typeMapper;
  249. _ef = ef;
  250. }
  251. public string Property(EdmProperty edmProperty)
  252. {
  253. return string.Format(
  254. CultureInfo.InvariantCulture,
  255. "{0} {1} {2} {{ {3}get; {4}set; }}",
  256. Accessibility.ForProperty(edmProperty),
  257. _typeMapper.GetTypeName(edmProperty.TypeUsage),
  258. _code.Escape(edmProperty),
  259. _code.SpaceAfter(Accessibility.ForGetter(edmProperty)),
  260. _code.SpaceAfter(Accessibility.ForSetter(edmProperty)));
  261. }
  262. public string NavigationProperty(NavigationProperty navProp)
  263. {
  264. var endType = _typeMapper.GetTypeName(navProp.ToEndMember.GetEntityType());
  265. return string.Format(
  266. CultureInfo.InvariantCulture,
  267. "{0} {1} {2} {{ {3}get; {4}set; }}",
  268. AccessibilityAndVirtual(Accessibility.ForNavigationProperty(navProp)),
  269. navProp.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many ? ("ICollection<" + endType + ">") : endType,
  270. _code.Escape(navProp),
  271. _code.SpaceAfter(Accessibility.ForGetter(navProp)),
  272. _code.SpaceAfter(Accessibility.ForSetter(navProp)));
  273. }
  274. public string AccessibilityAndVirtual(string accessibility)
  275. {
  276. return accessibility + (accessibility != "private" ? " virtual" : "");
  277. }
  278. public string EntityClassOpening(EntityType entity)
  279. {
  280. return string.Format(
  281. CultureInfo.InvariantCulture,
  282. "{0} {1}partial class {2}{3}",
  283. Accessibility.ForType(entity),
  284. _code.SpaceAfter(_code.AbstractOption(entity)),
  285. _code.Escape(entity),
  286. _code.StringBefore(" : ", _typeMapper.GetTypeName(entity.BaseType)));
  287. }
  288. public string EnumOpening(SimpleType enumType)
  289. {
  290. return string.Format(
  291. CultureInfo.InvariantCulture,
  292. "{0} enum {1} : {2}",
  293. Accessibility.ForType(enumType),
  294. _code.Escape(enumType),
  295. _code.Escape(_typeMapper.UnderlyingClrType(enumType)));
  296. }
  297. public void WriteFunctionParameters(EdmFunction edmFunction, Action<string, string, string, string> writeParameter)
  298. {
  299. var parameters = FunctionImportParameter.Create(edmFunction.Parameters, _code, _ef);
  300. foreach (var parameter in parameters.Where(p => p.NeedsLocalVariable))
  301. {
  302. var isNotNull = parameter.IsNullableOfT ? parameter.FunctionParameterName + ".HasValue" : parameter.FunctionParameterName + " != null";
  303. var notNullInit = "new ObjectParameter(\"" + parameter.EsqlParameterName + "\", " + parameter.FunctionParameterName + ")";
  304. var nullInit = "new ObjectParameter(\"" + parameter.EsqlParameterName + "\", typeof(" + TypeMapper.FixNamespaces(parameter.RawClrTypeName) + "))";
  305. writeParameter(parameter.LocalVariableName, isNotNull, notNullInit, nullInit);
  306. }
  307. }
  308. public string ComposableFunctionMethod(EdmFunction edmFunction, string modelNamespace)
  309. {
  310. var parameters = _typeMapper.GetParameters(edmFunction);
  311. return string.Format(
  312. CultureInfo.InvariantCulture,
  313. "{0} IQueryable<{1}> {2}({3})",
  314. AccessibilityAndVirtual(Accessibility.ForMethod(edmFunction)),
  315. _typeMapper.GetTypeName(_typeMapper.GetReturnType(edmFunction), modelNamespace),
  316. _code.Escape(edmFunction),
  317. string.Join(", ", parameters.Select(p => TypeMapper.FixNamespaces(p.FunctionParameterType) + " " + p.FunctionParameterName).ToArray()));
  318. }
  319. public string ComposableCreateQuery(EdmFunction edmFunction, string modelNamespace)
  320. {
  321. var parameters = _typeMapper.GetParameters(edmFunction);
  322. return string.Format(
  323. CultureInfo.InvariantCulture,
  324. "return ((IObjectContextAdapter)this).ObjectContext.CreateQuery<{0}>(\"[{1}].[{2}]({3})\"{4});",
  325. _typeMapper.GetTypeName(_typeMapper.GetReturnType(edmFunction), modelNamespace),
  326. edmFunction.NamespaceName,
  327. edmFunction.Name,
  328. string.Join(", ", parameters.Select(p => "@" + p.EsqlParameterName).ToArray()),
  329. _code.StringBefore(", ", string.Join(", ", parameters.Select(p => p.ExecuteParameterName).ToArray())));
  330. }
  331. public string FunctionMethod(EdmFunction edmFunction, string modelNamespace, bool includeMergeOption)
  332. {
  333. var parameters = _typeMapper.GetParameters(edmFunction);
  334. var returnType = _typeMapper.GetReturnType(edmFunction);
  335. var paramList = String.Join(", ", parameters.Select(p => TypeMapper.FixNamespaces(p.FunctionParameterType) + " " + p.FunctionParameterName).ToArray());
  336. if (includeMergeOption)
  337. {
  338. paramList = _code.StringAfter(paramList, ", ") + "MergeOption mergeOption";
  339. }
  340. return string.Format(
  341. CultureInfo.InvariantCulture,
  342. "{0} {1} {2}({3})",
  343. AccessibilityAndVirtual(Accessibility.ForMethod(edmFunction)),
  344. returnType == null ? "int" : "ObjectResult<" + _typeMapper.GetTypeName(returnType, modelNamespace) + ">",
  345. _code.Escape(edmFunction),
  346. paramList);
  347. }
  348. public string ExecuteFunction(EdmFunction edmFunction, string modelNamespace, bool includeMergeOption)
  349. {
  350. var parameters = _typeMapper.GetParameters(edmFunction);
  351. var returnType = _typeMapper.GetReturnType(edmFunction);
  352. var callParams = _code.StringBefore(", ", String.Join(", ", parameters.Select(p => p.ExecuteParameterName).ToArray()));
  353. if (includeMergeOption)
  354. {
  355. callParams = ", mergeOption" + callParams;
  356. }
  357. return string.Format(
  358. CultureInfo.InvariantCulture,
  359. "return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction{0}(\"{1}\"{2});",
  360. returnType == null ? "" : "<" + _typeMapper.GetTypeName(returnType, modelNamespace) + ">",
  361. edmFunction.Name,
  362. callParams);
  363. }
  364. public string DbSet(EntitySet entitySet)
  365. {
  366. return string.Format(
  367. CultureInfo.InvariantCulture,
  368. "{0} virtual DbSet<{1}> {2} {{ get; set; }}",
  369. Accessibility.ForReadOnlyProperty(entitySet),
  370. _typeMapper.GetTypeName(entitySet.ElementType),
  371. _code.Escape(entitySet));
  372. }
  373. public string UsingDirectives(bool inHeader, bool includeCollections = true)
  374. {
  375. return inHeader == string.IsNullOrEmpty(_code.VsNamespaceSuggestion())
  376. ? string.Format(
  377. CultureInfo.InvariantCulture,
  378. "{0}using System;{1}" +
  379. "{2}",
  380. inHeader ? Environment.NewLine : "",
  381. includeCollections ? (Environment.NewLine + "using System.Collections.Generic;") : "",
  382. inHeader ? "" : Environment.NewLine)
  383. : "";
  384. }
  385. }
  386. public class TypeMapper
  387. {
  388. private const string ExternalTypeNameAttributeName = @"http://schemas.microsoft.com/ado/2006/04/codegeneration:ExternalTypeName";
  389. private readonly System.Collections.IList _errors;
  390. private readonly CodeGenerationTools _code;
  391. private readonly MetadataTools _ef;
  392. public TypeMapper(CodeGenerationTools code, MetadataTools ef, System.Collections.IList errors)
  393. {
  394. ArgumentNotNull(code, "code");
  395. ArgumentNotNull(ef, "ef");
  396. ArgumentNotNull(errors, "errors");
  397. _code = code;
  398. _ef = ef;
  399. _errors = errors;
  400. }
  401. public static string FixNamespaces(string typeName)
  402. {
  403. return typeName.Replace("System.Data.Spatial.", "System.Data.Entity.Spatial.");
  404. }
  405. public string GetTypeName(TypeUsage typeUsage)
  406. {
  407. return typeUsage == null ? null : GetTypeName(typeUsage.EdmType, _ef.IsNullable(typeUsage), modelNamespace: null);
  408. }
  409. public string GetTypeName(EdmType edmType)
  410. {
  411. return GetTypeName(edmType, isNullable: null, modelNamespace: null);
  412. }
  413. public string GetTypeName(TypeUsage typeUsage, string modelNamespace)
  414. {
  415. return typeUsage == null ? null : GetTypeName(typeUsage.EdmType, _ef.IsNullable(typeUsage), modelNamespace);
  416. }
  417. public string GetTypeName(EdmType edmType, string modelNamespace)
  418. {
  419. return GetTypeName(edmType, isNullable: null, modelNamespace: modelNamespace);
  420. }
  421. public string GetTypeName(EdmType edmType, bool? isNullable, string modelNamespace)
  422. {
  423. if (edmType == null)
  424. {
  425. return null;
  426. }
  427. var collectionType = edmType as CollectionType;
  428. if (collectionType != null)
  429. {
  430. return String.Format(CultureInfo.InvariantCulture, "ICollection<{0}>", GetTypeName(collectionType.TypeUsage, modelNamespace));
  431. }
  432. var typeName = _code.Escape(edmType.MetadataProperties
  433. .Where(p => p.Name == ExternalTypeNameAttributeName)
  434. .Select(p => (string)p.Value)
  435. .FirstOrDefault())
  436. ?? (modelNamespace != null && edmType.NamespaceName != modelNamespace ?
  437. _code.CreateFullName(_code.EscapeNamespace(edmType.NamespaceName), _code.Escape(edmType)) :
  438. _code.Escape(edmType));
  439. if (edmType is StructuralType)
  440. {
  441. return typeName;
  442. }
  443. if (edmType is SimpleType)
  444. {
  445. var clrType = UnderlyingClrType(edmType);
  446. if (!IsEnumType(edmType))
  447. {
  448. typeName = _code.Escape(clrType);
  449. }
  450. typeName = FixNamespaces(typeName);
  451. return clrType.IsValueType && isNullable == true ?
  452. String.Format(CultureInfo.InvariantCulture, "Nullable<{0}>", typeName) :
  453. typeName;
  454. }
  455. throw new ArgumentException("edmType");
  456. }
  457. public Type UnderlyingClrType(EdmType edmType)
  458. {
  459. ArgumentNotNull(edmType, "edmType");
  460. var primitiveType = edmType as PrimitiveType;
  461. if (primitiveType != null)
  462. {
  463. return primitiveType.ClrEquivalentType;
  464. }
  465. if (IsEnumType(edmType))
  466. {
  467. return GetEnumUnderlyingType(edmType).ClrEquivalentType;
  468. }
  469. return typeof(object);
  470. }
  471. public object GetEnumMemberValue(MetadataItem enumMember)
  472. {
  473. ArgumentNotNull(enumMember, "enumMember");
  474. var valueProperty = enumMember.GetType().GetProperty("Value");
  475. return valueProperty == null ? null : valueProperty.GetValue(enumMember, null);
  476. }
  477. public string GetEnumMemberName(MetadataItem enumMember)
  478. {
  479. ArgumentNotNull(enumMember, "enumMember");
  480. var nameProperty = enumMember.GetType().GetProperty("Name");
  481. return nameProperty == null ? null : (string)nameProperty.GetValue(enumMember, null);
  482. }
  483. public System.Collections.IEnumerable GetEnumMembers(EdmType enumType)
  484. {
  485. ArgumentNotNull(enumType, "enumType");
  486. var membersProperty = enumType.GetType().GetProperty("Members");
  487. return membersProperty != null
  488. ? (System.Collections.IEnumerable)membersProperty.GetValue(enumType, null)
  489. : Enumerable.Empty<MetadataItem>();
  490. }
  491. public bool EnumIsFlags(EdmType enumType)
  492. {
  493. ArgumentNotNull(enumType, "enumType");
  494. var isFlagsProperty = enumType.GetType().GetProperty("IsFlags");
  495. return isFlagsProperty != null && (bool)isFlagsProperty.GetValue(enumType, null);
  496. }
  497. public bool IsEnumType(GlobalItem edmType)
  498. {
  499. ArgumentNotNull(edmType, "edmType");
  500. return edmType.GetType().Name == "EnumType";
  501. }
  502. public PrimitiveType GetEnumUnderlyingType(EdmType enumType)
  503. {
  504. ArgumentNotNull(enumType, "enumType");
  505. return (PrimitiveType)enumType.GetType().GetProperty("UnderlyingType").GetValue(enumType, null);
  506. }
  507. public string CreateLiteral(object value)
  508. {
  509. if (value == null || value.GetType() != typeof(TimeSpan))
  510. {
  511. return _code.CreateLiteral(value);
  512. }
  513. return string.Format(CultureInfo.InvariantCulture, "new TimeSpan({0})", ((TimeSpan)value).Ticks);
  514. }
  515. public bool VerifyCaseInsensitiveTypeUniqueness(IEnumerable<string> types, string sourceFile)
  516. {
  517. ArgumentNotNull(types, "types");
  518. ArgumentNotNull(sourceFile, "sourceFile");
  519. var hash = new HashSet<string>(StringComparer.InvariantCultureIgnoreCase);
  520. if (types.Any(item => !hash.Add(item)))
  521. {
  522. _errors.Add(
  523. new CompilerError(sourceFile, -1, -1, "6023",
  524. String.Format(CultureInfo.CurrentCulture, CodeGenerationTools.GetResourceString("Template_CaseInsensitiveTypeConflict"))));
  525. return false;
  526. }
  527. return true;
  528. }
  529. public IEnumerable<SimpleType> GetEnumItemsToGenerate(IEnumerable<GlobalItem> itemCollection)
  530. {
  531. return GetItemsToGenerate<SimpleType>(itemCollection)
  532. .Where(e => IsEnumType(e));
  533. }
  534. public IEnumerable<T> GetItemsToGenerate<T>(IEnumerable<GlobalItem> itemCollection) where T: EdmType
  535. {
  536. return itemCollection
  537. .OfType<T>()
  538. .Where(i => !i.MetadataProperties.Any(p => p.Name == ExternalTypeNameAttributeName))
  539. .OrderBy(i => i.Name);
  540. }
  541. public IEnumerable<string> GetAllGlobalItems(IEnumerable<GlobalItem> itemCollection)
  542. {
  543. return itemCollection
  544. .Where(i => i is EntityType || i is ComplexType || i is EntityContainer || IsEnumType(i))
  545. .Select(g => GetGlobalItemName(g));
  546. }
  547. public string GetGlobalItemName(GlobalItem item)
  548. {
  549. if (item is EdmType)
  550. {
  551. return ((EdmType)item).Name;
  552. }
  553. else
  554. {
  555. return ((EntityContainer)item).Name;
  556. }
  557. }
  558. public IEnumerable<EdmProperty> GetSimpleProperties(EntityType type)
  559. {
  560. return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type);
  561. }
  562. public IEnumerable<EdmProperty> GetSimpleProperties(ComplexType type)
  563. {
  564. return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type);
  565. }
  566. public IEnumerable<EdmProperty> GetComplexProperties(EntityType type)
  567. {
  568. return type.Properties.Where(p => p.TypeUsage.EdmType is ComplexType && p.DeclaringType == type);
  569. }
  570. public IEnumerable<EdmProperty> GetComplexProperties(ComplexType type)
  571. {
  572. return type.Properties.Where(p => p.TypeUsage.EdmType is ComplexType && p.DeclaringType == type);
  573. }
  574. public IEnumerable<EdmProperty> GetPropertiesWithDefaultValues(EntityType type)
  575. {
  576. return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type && p.DefaultValue != null);
  577. }
  578. public IEnumerable<EdmProperty> GetPropertiesWithDefaultValues(ComplexType type)
  579. {
  580. return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type && p.DefaultValue != null);
  581. }
  582. public IEnumerable<NavigationProperty> GetNavigationProperties(EntityType type)
  583. {
  584. return type.NavigationProperties.Where(np => np.DeclaringType == type);
  585. }
  586. public IEnumerable<NavigationProperty> GetCollectionNavigationProperties(EntityType type)
  587. {
  588. return type.NavigationProperties.Where(np => np.DeclaringType == type && np.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many);
  589. }
  590. public FunctionParameter GetReturnParameter(EdmFunction edmFunction)
  591. {
  592. ArgumentNotNull(edmFunction, "edmFunction");
  593. var returnParamsProperty = edmFunction.GetType().GetProperty("ReturnParameters");
  594. return returnParamsProperty == null
  595. ? edmFunction.ReturnParameter
  596. : ((IEnumerable<FunctionParameter>)returnParamsProperty.GetValue(edmFunction, null)).FirstOrDefault();
  597. }
  598. public bool IsComposable(EdmFunction edmFunction)
  599. {
  600. ArgumentNotNull(edmFunction, "edmFunction");
  601. var isComposableProperty = edmFunction.GetType().GetProperty("IsComposableAttribute");
  602. return isComposableProperty != null && (bool)isComposableProperty.GetValue(edmFunction, null);
  603. }
  604. public IEnumerable<FunctionImportParameter> GetParameters(EdmFunction edmFunction)
  605. {
  606. return FunctionImportParameter.Create(edmFunction.Parameters, _code, _ef);
  607. }
  608. public TypeUsage GetReturnType(EdmFunction edmFunction)
  609. {
  610. var returnParam = GetReturnParameter(edmFunction);
  611. return returnParam == null ? null : _ef.GetElementType(returnParam.TypeUsage);
  612. }
  613. public bool GenerateMergeOptionFunction(EdmFunction edmFunction, bool includeMergeOption)
  614. {
  615. var returnType = GetReturnType(edmFunction);
  616. return !includeMergeOption && returnType != null && returnType.EdmType.BuiltInTypeKind == BuiltInTypeKind.EntityType;
  617. }
  618. }
  619. public static void ArgumentNotNull<T>(T arg, string name) where T : class
  620. {
  621. if (arg == null)
  622. {
  623. throw new ArgumentNullException(name);
  624. }
  625. }
  626. #>