EMISOnline.Entitis.Mapping.tt 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542
  1. <#@ template language="C#" debug="false" hostspecific="true"#>
  2. <#@ include file="EF.Utility.CS.ttinclude"#>
  3. <#@ assembly name="$(DevEnvDir)Microsoft.Data.Entity.Design.DatabaseGeneration.dll"#>
  4. <#@ import namespace="Microsoft.Data.Entity.Design.DatabaseGeneration" #>
  5. <#@ import namespace="System.Text"#>
  6. <#@ output extension=".cs"#><#
  7. CodeGenerationTools code = new CodeGenerationTools(this);
  8. CodeRegion region = new CodeRegion(this, 1);
  9. MetadataTools ef = new MetadataTools(this);
  10. string inputFile = @"EMISOnlineContext.edmx";
  11. var loadResult = LoadMetadata(inputFile);
  12. EdmItemCollection itemCollection = loadResult.EdmItems;
  13. var propertyToColumnMapping = loadResult.PropertyToColumnMapping;
  14. var manyToManyMappings = loadResult.ManyToManyMappings;
  15. var tphMappings = loadResult.TphMappings;
  16. string namespaceName = code.VsNamespaceSuggestion();
  17. string mapClassSuffix = "_Mapping";
  18. EntityFrameworkTemplateFileManager fileManager = EntityFrameworkTemplateFileManager.Create(this);
  19. WriteHeader(fileManager);
  20. foreach (EntityType entity in itemCollection.GetItems<EntityType>().OrderBy(e => e.Name))
  21. {
  22. fileManager.StartNewFile(entity.Name + mapClassSuffix + ".cs");
  23. BeginNamespace(namespaceName, code);
  24. #>
  25. #pragma warning disable 1573
  26. using System;
  27. using System.Collections.Generic;
  28. using System.ComponentModel.DataAnnotations;
  29. using System.Data.Common;
  30. using System.Data.Entity;
  31. using System.Data.Entity.ModelConfiguration;
  32. using System.Data.Entity.Infrastructure;
  33. using System.ComponentModel.DataAnnotations.Schema;
  34. internal partial class <#=code.Escape(entity) + mapClassSuffix#><#=string.Format(" : EntityTypeConfiguration<{0}>", code.Escape(entity))#>
  35. {
  36. public <#=code.Escape(entity) + mapClassSuffix#>()
  37. {
  38. <#
  39. string hasKey;
  40. if(entity.KeyMembers.Count<EdmMember>() == 1)
  41. hasKey = string.Format(".HasKey(t => t.{0})", entity.KeyMembers[0].Name);
  42. else
  43. hasKey = string.Format(".HasKey(t => new {{{0}}})", string.Join(", ", entity.KeyMembers.Select(m => "t." + m.Name)));
  44. #>
  45. this<#=hasKey#>;
  46. <#
  47. if(tphMappings.Keys.Contains(entity))
  48. {
  49. foreach(KeyValuePair<EntityType, Dictionary<EdmProperty, string>> entityMapping in tphMappings[entity])
  50. {
  51. #>
  52. this.Map<<#=entityMapping.Key.Name #>>(m =>
  53. {
  54. <#
  55. foreach(KeyValuePair<EdmProperty, string> propertyMapping in entityMapping.Value)
  56. {
  57. string val;
  58. switch(propertyMapping.Key.TypeUsage.EdmType.BaseType.FullName)
  59. {
  60. case "Edm.String":
  61. val="\""+propertyMapping.Value+"\"";
  62. break;
  63. default:
  64. val=propertyMapping.Value;
  65. break;
  66. }
  67. #> m.Requires("<#=propertyMapping.Key.Name#>").HasValue(<#=val#>);
  68. <#
  69. }
  70. #>});
  71. <#
  72. }
  73. }
  74. var entityPropertyToColumnMapping = propertyToColumnMapping[entity];
  75. #>
  76. this.ToTable("<#=ToTable(entityPropertyToColumnMapping.Item1)#>");
  77. <#
  78. foreach (EdmProperty property in entity.Properties)
  79. {
  80. string generateOption = GetGenerationOption(property, entity);
  81. string required = "";
  82. string unicCode = "";
  83. string fixedLength = "";
  84. string maxLength = "";
  85. PrimitiveType edmType = (PrimitiveType) property.TypeUsage.EdmType;
  86. if(edmType.ClrEquivalentType == typeof(string) || edmType.ClrEquivalentType == typeof(byte[]))
  87. {
  88. if (!property.Nullable)
  89. required = ".IsRequired()";
  90. Facet unicodeFacet = property.TypeUsage.Facets.SingleOrDefault(f => f.Name == "Unicode");
  91. unicCode = unicodeFacet != null && unicodeFacet.Value != null && (!(bool)unicodeFacet.Value) ? ".IsUnicode(false)" : "";
  92. Facet fixedLengthFacet = property.TypeUsage.Facets.SingleOrDefault(f => f.Name == "FixedLength");
  93. fixedLength = fixedLengthFacet != null && fixedLengthFacet.Value != null && ((bool)fixedLengthFacet.Value) ? ".IsFixedLength()" : "";
  94. Facet maxLengthFacet = property.TypeUsage.Facets.SingleOrDefault(f => f.Name == "MaxLength");
  95. maxLength = (maxLengthFacet != null && maxLengthFacet.Value != null && !maxLengthFacet.IsUnbounded) ? string.Format(".HasMaxLength({0})", maxLengthFacet.Value) : "";
  96. }
  97. if(!entityPropertyToColumnMapping.Item2.Keys.Contains(property)) continue;
  98. string hasColumnName = string.Format(".HasColumnName(\"{0}\")", entityPropertyToColumnMapping.Item2[property].Name);
  99. #>
  100. this.Property(t => t.<#= property.Name#>)<#=hasColumnName + generateOption + required + unicCode + fixedLength + maxLength #>;
  101. <#
  102. }
  103. var navigationProperties = entity.NavigationProperties.Where(np =>
  104. {
  105. return ((np.DeclaringType == entity) &&
  106. ((AssociationType) np.RelationshipType).IsForeignKey) &&
  107. (((AssociationType) np.RelationshipType).ReferentialConstraints.Single<ReferentialConstraint>().ToRole == np.FromEndMember);
  108. });
  109. foreach(NavigationProperty navProperty in navigationProperties)
  110. {
  111. StringBuilder navPropBuilder = new StringBuilder();
  112. NavigationProperty navPropertyBackReference = navProperty.ToEndMember.GetEntityType().NavigationProperties
  113. .Where(npBack => npBack.RelationshipType == navProperty.RelationshipType && npBack != navProperty)
  114. .Single();
  115. AssociationType associationType = (AssociationType) navProperty.RelationshipType;
  116. if (navProperty.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.One)
  117. navPropBuilder.AppendFormat("this.HasRequired(t => t.{0})", code.Escape(navProperty));
  118. else
  119. navPropBuilder.AppendFormat("this.HasOptional(t => t.{0})", code.Escape(navProperty));
  120. if (navProperty.FromEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many)
  121. {
  122. navPropBuilder.AppendFormat(".WithMany(t => t.{0})", code.Escape(navPropertyBackReference));
  123. if (associationType.ReferentialConstraints.Single().ToProperties.Count == 1)
  124. navPropBuilder.AppendFormat(".HasForeignKey(d => d.{0})", associationType.ReferentialConstraints.Single().ToProperties.Single().Name);
  125. else
  126. navPropBuilder.AppendFormat(".HasForeignKey(d => new {{{0}}})", string.Join(", ", associationType.ReferentialConstraints.Single().ToProperties.Select(p => "d." + p.Name)));
  127. }
  128. else
  129. {
  130. navPropBuilder.AppendFormat(".WithOptional(t => t.{0})", code.Escape(navPropertyBackReference));
  131. }
  132. #>
  133. <#= navPropBuilder.ToString() #>;
  134. <#
  135. }
  136. var manyToMany = entity.NavigationProperties.Where(np =>
  137. np.DeclaringType == entity
  138. && np.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many
  139. && np.FromEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many
  140. && np.RelationshipType.RelationshipEndMembers.First() == np.FromEndMember);
  141. var manyToManyBuilder = new StringBuilder();
  142. foreach (NavigationProperty navProperty in manyToMany)
  143. {
  144. var member = navProperty.ToEndMember.GetEntityType().NavigationProperties
  145. .Single(nv => (nv.RelationshipType == navProperty.RelationshipType) && (nv != navProperty));
  146. var relationshipType = (AssociationType) navProperty.RelationshipType;
  147. Tuple<EntitySet, Dictionary<RelationshipEndMember, Dictionary<EdmMember, string>>> tuple;
  148. if(manyToManyMappings.TryGetValue(relationshipType, out tuple))
  149. {
  150. string middleTableName = this.ToTable(tuple.Item1);
  151. var leftType = (EntityType) navProperty.DeclaringType;
  152. Dictionary<EdmMember, string> leftKeyMappings = tuple.Item2[navProperty.FromEndMember];
  153. string leftColumns = string.Join(", ", leftType.KeyMembers.Select(m => "\"" + leftKeyMappings[m] + "\""));
  154. var rightType = (EntityType) member.DeclaringType;
  155. Dictionary<EdmMember, string> rightKeyMappings = tuple.Item2[member.FromEndMember];
  156. string rightColumns = string.Join(", ", rightType.KeyMembers.Select(m => "\"" + rightKeyMappings[m] + "\""));
  157. #>
  158. this.HasMany(t => t.<#= code.Escape(navProperty) #>).WithMany(t => t.<#= code.Escape(member) #>)
  159. .Map(m =>
  160. {
  161. m.ToTable("<#= middleTableName #>");
  162. m.MapLeftKey(<#= leftColumns #>);
  163. m.MapRightKey(<#= rightColumns #>);
  164. });
  165. <#
  166. }
  167. }
  168. #>
  169. }
  170. }
  171. <#
  172. EndNamespace(namespaceName);
  173. }
  174. #>
  175. <#
  176. if (!VerifyTypesAreCaseInsensitiveUnique(itemCollection))
  177. {
  178. return "";
  179. }
  180. fileManager.Process();
  181. #>
  182. <#+
  183. string GetResourceString(string resourceName)
  184. {
  185. if(_resourceManager2 == null)
  186. {
  187. _resourceManager2 = new System.Resources.ResourceManager("System.Data.Entity.Design", typeof(System.Data.Entity.Design.MetadataItemCollectionFactory).Assembly);
  188. }
  189. return _resourceManager2.GetString(resourceName, null);
  190. }
  191. System.Resources.ResourceManager _resourceManager2;
  192. void WriteHeader(EntityFrameworkTemplateFileManager fileManager)
  193. {
  194. fileManager.StartHeader();
  195. #>
  196. //------------------------------------------------------------------------------
  197. // <auto-generated>
  198. // This code was generated from a template.
  199. //
  200. // Manual changes to this file may cause unexpected behavior in your application.
  201. // Manual changes to this file will be overwritten if the code is regenerated.
  202. // </auto-generated>
  203. //------------------------------------------------------------------------------
  204. <#+
  205. fileManager.EndBlock();
  206. }
  207. void BeginNamespace(string namespaceName, CodeGenerationTools code)
  208. {
  209. CodeRegion region = new CodeRegion(this);
  210. if (!String.IsNullOrEmpty(namespaceName))
  211. {
  212. #>
  213. namespace <#=code.EscapeNamespace(namespaceName)#>
  214. {
  215. <#+
  216. PushIndent(CodeRegion.GetIndent(1));
  217. }
  218. }
  219. void EndNamespace(string namespaceName)
  220. {
  221. if (!String.IsNullOrEmpty(namespaceName))
  222. {
  223. PopIndent();
  224. #>
  225. }
  226. <#+
  227. }
  228. }
  229. string ToTable(EntitySet entitySet)
  230. {
  231. string toTable = entitySet.Name;
  232. string schema = entitySet.GetSchemaName();
  233. if(!string.IsNullOrWhiteSpace(schema) && schema != "dbo" && toTable.IndexOf("V_")<0)
  234. toTable += "\", \"" + schema;
  235. return toTable;
  236. }
  237. bool VerifyTypesAreCaseInsensitiveUnique(EdmItemCollection itemCollection)
  238. {
  239. var alreadySeen = new Dictionary<string, bool>(StringComparer.OrdinalIgnoreCase);
  240. foreach(var type in itemCollection.GetItems<StructuralType>())
  241. {
  242. if (!(type is EntityType || type is ComplexType))
  243. {
  244. continue;
  245. }
  246. if (alreadySeen.ContainsKey(type.FullName))
  247. {
  248. Error(String.Format(CultureInfo.CurrentCulture, "This template does not support types that differ only by case, the types {0} are not supported", type.FullName));
  249. return false;
  250. }
  251. else
  252. {
  253. alreadySeen.Add(type.FullName, true);
  254. }
  255. }
  256. return true;
  257. }
  258. string GetGenerationOption(EdmProperty property, EntityType entity)
  259. {
  260. string result = "";
  261. bool isPk = entity.KeyMembers.Contains(property);
  262. MetadataProperty storeGeneratedPatternProperty = null;
  263. string storeGeneratedPatternPropertyValue = "None";
  264. if(property.MetadataProperties.TryGetValue(MetadataConsts.EDM_ANNOTATION_09_02 + ":StoreGeneratedPattern", false, out storeGeneratedPatternProperty))
  265. storeGeneratedPatternPropertyValue = storeGeneratedPatternProperty.Value.ToString();
  266. PrimitiveType edmType = (PrimitiveType) property.TypeUsage.EdmType;
  267. if (storeGeneratedPatternPropertyValue == "Computed")
  268. {
  269. result = ".HasDatabaseGeneratedOption(DatabaseGeneratedOption.Computed)";
  270. }
  271. else if ((edmType.ClrEquivalentType == typeof(decimal)) ||(edmType.ClrEquivalentType == typeof(int)) || (edmType.ClrEquivalentType == typeof(short)) || (edmType.ClrEquivalentType == typeof(long)))
  272. {
  273. if (isPk && (storeGeneratedPatternPropertyValue != "Identity"))
  274. result = ".HasDatabaseGeneratedOption(DatabaseGeneratedOption.None)";
  275. else if (isPk && (storeGeneratedPatternPropertyValue == "Identity"))
  276. result = ".HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity)";
  277. else if ((!isPk || (entity.KeyMembers.Count > 1)) && (storeGeneratedPatternPropertyValue == "Identity"))
  278. result = ".HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity)";
  279. }
  280. return result;
  281. }
  282. MetadataLoadResult LoadMetadata(string inputFile)
  283. {
  284. var loader = new MetadataLoader(this);
  285. bool loaded = false;
  286. EdmItemCollection edmItemCollection = loader.CreateEdmItemCollection(inputFile);
  287. StoreItemCollection storeItemCollection = null;
  288. if (loader.TryCreateStoreItemCollection(inputFile, out storeItemCollection))
  289. {
  290. StorageMappingItemCollection storageMappingItemCollection;
  291. if (loader.TryCreateStorageMappingItemCollection(inputFile, edmItemCollection, storeItemCollection, out storageMappingItemCollection))
  292. loaded = true;
  293. }
  294. if(loaded == false)
  295. throw new Exception("Cannot load a metadata from the file " + inputFile);
  296. var mappingMetadata = LoadMappingMetadata(inputFile);
  297. var mappingNode = mappingMetadata.Item1;
  298. var nsmgr = mappingMetadata.Item2;
  299. var allEntitySets = storeItemCollection.GetAllEntitySets();
  300. return new MetadataLoadResult
  301. {
  302. EdmItems = edmItemCollection,
  303. PropertyToColumnMapping = BuildEntityMappings(mappingNode, nsmgr, edmItemCollection.GetItems<EntityType>(), edmItemCollection.GetAllEntitySets(), allEntitySets),
  304. ManyToManyMappings = BuildManyToManyMappings(mappingNode, nsmgr, edmItemCollection.GetAllAssociationSets(), allEntitySets),
  305. TphMappings=BuildTPHMappings(mappingNode, nsmgr, edmItemCollection.GetItems<EntityType>(), edmItemCollection.GetAllEntitySets(), allEntitySets)
  306. };
  307. }
  308. private Tuple<XmlNode, XmlNamespaceManager> LoadMappingMetadata(string inputFile)
  309. {
  310. var xmlDoc = new XmlDocument();
  311. xmlDoc.Load(Host.ResolvePath(inputFile));
  312. var schemaConstantsList = new SchemaConsts[]
  313. {
  314. MetadataConsts.V2_SCHEMA_CONSTANTS,
  315. MetadataConsts.V1_SCHEMA_CONSTANTS
  316. };
  317. foreach (var schemaConstants in schemaConstantsList)
  318. {
  319. var nsmgr = new XmlNamespaceManager(xmlDoc.NameTable);
  320. nsmgr.AddNamespace("ef", schemaConstants.MslNamespace);
  321. nsmgr.AddNamespace("edmx", schemaConstants.EdmxNamespace);
  322. var mappingNode = xmlDoc.DocumentElement.SelectSingleNode("./*/edmx:Mappings", nsmgr);
  323. if(mappingNode != null)
  324. return Tuple.Create(mappingNode, nsmgr);
  325. }
  326. throw new Exception(GetResourceString("Template_UnsupportedSchema"));
  327. }
  328. private Dictionary<EntityType, Dictionary<EntityType, Dictionary<EdmProperty, string>>> BuildTPHMappings(XmlNode mappingNode, XmlNamespaceManager nsmgr, IEnumerable<EntityType> entityTypes, IEnumerable<EntitySet> entitySets, IEnumerable<EntitySet> tableSets)
  329. {
  330. var dictionary = new Dictionary<EntityType, Dictionary<EntityType, Dictionary<EdmProperty, string>>>();
  331. foreach (EntitySet set in entitySets)
  332. {
  333. XmlNodeList nodes = mappingNode.SelectNodes(string.Format(".//ef:EntitySetMapping[@Name=\"{0}\"]/ef:EntityTypeMapping/ef:MappingFragment", set.Name), nsmgr);
  334. foreach(XmlNode node in nodes)
  335. {
  336. string typeName=node.ParentNode.Attributes["TypeName"].Value;
  337. if(typeName.StartsWith("IsTypeOf("))
  338. typeName=typeName.Substring("IsTypeOf(".Length, typeName.Length-"IsTypeOf()".Length);
  339. EntityType type=entityTypes.Single(z=>z.FullName==typeName);
  340. string tableName = node.Attributes["StoreEntitySet"].Value;
  341. EntitySet set2 = tableSets.Single(entitySet => entitySet.Name == tableName);
  342. var entityMap = new Dictionary<EdmProperty, string>();
  343. XmlNodeList propertyNodes = node.SelectNodes("./ef:Condition", nsmgr);
  344. if(propertyNodes.Count==0) continue;
  345. foreach(XmlNode propertyNode in propertyNodes)
  346. {
  347. string str = propertyNode.Attributes["ColumnName"].Value;
  348. EdmProperty property2 = set2.ElementType.Properties[str];
  349. string val=propertyNode.Attributes["Value"].Value;
  350. entityMap.Add(property2, val);
  351. }
  352. EntityType baseType=(EntityType)(type.BaseType??type);
  353. if(!dictionary.Keys.Contains(baseType))
  354. {
  355. var entityMappings=new Dictionary<EntityType, Dictionary<EdmProperty, string>>();
  356. //entityMappings.Add(type,entityMap);
  357. dictionary.Add(baseType, entityMappings);
  358. }
  359. dictionary[baseType].Add(type,entityMap);
  360. }
  361. }
  362. return dictionary;
  363. }
  364. private Dictionary<EntityType, Tuple<EntitySet, Dictionary<EdmProperty, EdmProperty>>> BuildEntityMappings(XmlNode mappingNode, XmlNamespaceManager nsmgr, IEnumerable<EntityType> entityTypes, IEnumerable<EntitySet> entitySets, IEnumerable<EntitySet> tableSets)
  365. {
  366. var dictionary = new Dictionary<EntityType, Tuple<EntitySet, Dictionary<EdmProperty, EdmProperty>>>();
  367. foreach (EntitySet set in entitySets)
  368. {
  369. XmlNodeList nodes = mappingNode.SelectNodes(string.Format(".//ef:EntitySetMapping[@Name=\"{0}\"]/ef:EntityTypeMapping/ef:MappingFragment", set.Name), nsmgr);
  370. foreach(XmlNode node in nodes)
  371. {
  372. string typeName=node.ParentNode.Attributes["TypeName"].Value;
  373. if(typeName.StartsWith("IsTypeOf("))
  374. typeName=typeName.Substring("IsTypeOf(".Length, typeName.Length-"IsTypeOf()".Length);
  375. EntityType type=entityTypes.Single(z=>z.FullName==typeName);
  376. string tableName = node.Attributes["StoreEntitySet"].Value;
  377. EntitySet set2 = tableSets.Single(entitySet => entitySet.Name == tableName);
  378. var entityMap = new Dictionary<EdmProperty, EdmProperty>();
  379. foreach (EdmProperty property in type.Properties)
  380. {
  381. XmlNode propertyNode = node.SelectSingleNode(string.Format("./ef:ScalarProperty[@Name=\"{0}\"]", property.Name), nsmgr);
  382. if(propertyNode == null) continue;
  383. string str = propertyNode.Attributes["ColumnName"].Value;
  384. EdmProperty property2 = set2.ElementType.Properties[str];
  385. entityMap.Add(property, property2);
  386. }
  387. dictionary.Add(type, Tuple.Create(set2, entityMap));
  388. }
  389. }
  390. return dictionary;
  391. }
  392. Dictionary<AssociationType, Tuple<EntitySet, Dictionary<RelationshipEndMember, Dictionary<EdmMember, string>>>> BuildManyToManyMappings(XmlNode mappingNode, XmlNamespaceManager nsmgr, IEnumerable<AssociationSet> associationSets, IEnumerable<EntitySet> tableSets)
  393. {
  394. var dictionary = new Dictionary<AssociationType, Tuple<EntitySet, Dictionary<RelationshipEndMember, Dictionary<EdmMember, string>>>>();
  395. foreach (AssociationSet associationSet in associationSets.Where(set => set.ElementType.IsManyToMany()))
  396. {
  397. XmlNode node = mappingNode.SelectSingleNode(string.Format("//ef:AssociationSetMapping[@Name=\"{0}\"]", associationSet.Name), nsmgr);
  398. string tableName = node.Attributes["StoreEntitySet"].Value;
  399. EntitySet entitySet = tableSets.Single(s => s.Name == tableName);
  400. var relationEndMap = new Dictionary<RelationshipEndMember, Dictionary<EdmMember, string>>();
  401. foreach (AssociationSetEnd end in associationSet.AssociationSetEnds)
  402. {
  403. var map = new Dictionary<EdmMember, string>();
  404. foreach (XmlNode endProperty in node.SelectSingleNode(string.Format("./ef:EndProperty[@Name=\"{0}\"]", end.Name), nsmgr).ChildNodes)
  405. {
  406. string str = endProperty.Attributes["Name"].Value;
  407. EdmProperty key = end.EntitySet.ElementType.Properties[str];
  408. string str2 = endProperty.Attributes["ColumnName"].Value;
  409. map.Add(key, str2);
  410. }
  411. relationEndMap.Add(end.CorrespondingAssociationEndMember, map);
  412. }
  413. dictionary.Add(associationSet.ElementType, Tuple.Create(entitySet, relationEndMap));
  414. }
  415. return dictionary;
  416. }
  417. public class MetadataLoadResult
  418. {
  419. public EdmItemCollection EdmItems { get; set; }
  420. public Dictionary<EntityType, Tuple<EntitySet, Dictionary<EdmProperty, EdmProperty>>> PropertyToColumnMapping { get; set; }
  421. public Dictionary<AssociationType, Tuple<EntitySet, Dictionary<RelationshipEndMember, Dictionary<EdmMember, string>>>> ManyToManyMappings { get; set; }
  422. public Dictionary<EntityType, Dictionary<EntityType, Dictionary<EdmProperty, string>>> TphMappings { get; set; }
  423. }
  424. /// <summary>
  425. /// Responsible for encapsulating the constants defined in Metadata
  426. /// </summary>
  427. public static class MetadataConsts
  428. {
  429. public const string CSDL_EXTENSION = ".csdl";
  430. public const string CSDL_EDMX_SECTION_NAME = "ConceptualModels";
  431. public const string CSDL_ROOT_ELEMENT_NAME = "Schema";
  432. public const string EDM_ANNOTATION_09_02 = "http://schemas.microsoft.com/ado/2009/02/edm/annotation";
  433. public const string SSDL_EXTENSION = ".ssdl";
  434. public const string SSDL_EDMX_SECTION_NAME = "StorageModels";
  435. public const string SSDL_ROOT_ELEMENT_NAME = "Schema";
  436. public const string MSL_EXTENSION = ".msl";
  437. public const string MSL_EDMX_SECTION_NAME = "Mappings";
  438. public const string MSL_ROOT_ELEMENT_NAME = "Mapping";
  439. public const string TT_TEMPLATE_NAME = "TemplateName";
  440. public const string TT_TEMPLATE_VERSION = "TemplateVersion";
  441. public const string TT_MINIMUM_ENTITY_FRAMEWORK_VERSION = "MinimumEntityFrameworkVersion";
  442. public const string DEFAULT_TEMPLATE_VERSION = "4.0";
  443. public static readonly SchemaConsts V1_SCHEMA_CONSTANTS = new SchemaConsts(
  444. "http://schemas.microsoft.com/ado/2007/06/edmx",
  445. "http://schemas.microsoft.com/ado/2006/04/edm",
  446. "http://schemas.microsoft.com/ado/2006/04/edm/ssdl",
  447. "urn:schemas-microsoft-com:windows:storage:mapping:CS",
  448. new Version("3.5"));
  449. public static readonly SchemaConsts V2_SCHEMA_CONSTANTS = new SchemaConsts(
  450. "http://schemas.microsoft.com/ado/2008/10/edmx",
  451. "http://schemas.microsoft.com/ado/2008/09/edm",
  452. "http://schemas.microsoft.com/ado/2009/02/edm/ssdl",
  453. "http://schemas.microsoft.com/ado/2008/09/mapping/cs",
  454. new Version("4.0"));
  455. public static readonly SchemaConsts V3_SCHEMA_CONSTANTS = new SchemaConsts(
  456. "http://schemas.microsoft.com/ado/2009/11/edmx",
  457. "http://schemas.microsoft.com/ado/2009/11/edm",
  458. "http://schemas.microsoft.com/ado/2009/11/edm/ssdl",
  459. "http://schemas.microsoft.com/ado/2009/11/mapping/cs",
  460. new Version("4.5"));
  461. }
  462. public struct SchemaConsts
  463. {
  464. public SchemaConsts(string edmxNamespace, string csdlNamespace, string ssdlNamespace, string mslNamespace, Version minimumTemplateVersion) : this()
  465. {
  466. EdmxNamespace = edmxNamespace;
  467. CsdlNamespace = csdlNamespace;
  468. SsdlNamespace = ssdlNamespace;
  469. MslNamespace = mslNamespace;
  470. MinimumTemplateVersion = minimumTemplateVersion;
  471. }
  472. public string EdmxNamespace { get; private set; }
  473. public string CsdlNamespace { get; private set; }
  474. public string SsdlNamespace { get; private set; }
  475. public string MslNamespace { get; private set; }
  476. public Version MinimumTemplateVersion { get; private set; }
  477. }
  478. #>