/// <summary> /// Initializes an instance of the EfMapping class /// </summary> /// <param name="db">The context to get the mapping from</param> public EfMapping(DbContext db) { this.TypeMappings = new Dictionary <Type, TypeMapping>(); var metadata = ((IObjectContextAdapter)db).ObjectContext.MetadataWorkspace; //EF61Test(metadata); // Conceptual part of the model has info about the shape of our entity classes var conceptualContainer = metadata.GetItems <EntityContainer>(DataSpace.CSpace).Single(); // Storage part of the model has info about the shape of our tables var storeContainer = metadata.GetItems <EntityContainer>(DataSpace.SSpace).Single(); // Object part of the model that contains info about the actual CLR types var objectItemCollection = ((ObjectItemCollection)metadata.GetItemCollection(DataSpace.OSpace)); // Loop thru each entity type in the model foreach (var set in conceptualContainer.BaseEntitySets.OfType <EntitySet>()) { // Find the mapping between conceptual and storage model for this entity set var mapping = metadata.GetItems <EntityContainerMapping>(DataSpace.CSSpace) .Single() .EntitySetMappings .Single(s => s.EntitySet == set); var typeMapping = new TypeMapping { TableMappings = new List <TableMapping>(), EntityType = GetClrType(metadata, objectItemCollection, set) }; this.TypeMappings.Add(typeMapping.EntityType, typeMapping); var tableMapping = new TableMapping { PropertyMappings = new List <PropertyMapping>(), }; var mappingToLookAt = mapping.EntityTypeMappings.FirstOrDefault(m => m.IsHierarchyMapping) ?? mapping.EntityTypeMappings.First(); tableMapping.Schema = mappingToLookAt.Fragments[0].StoreEntitySet.Schema; tableMapping.TableName = mappingToLookAt.Fragments[0].StoreEntitySet.Table ?? mappingToLookAt.Fragments[0].StoreEntitySet.Name; typeMapping.TableMappings.Add(tableMapping); Action <Type, System.Data.Entity.Core.Mapping.PropertyMapping, string> recurse = null; recurse = (t, item, path) => { if (item is ComplexPropertyMapping) { var complex = item as ComplexPropertyMapping; foreach (var child in complex.TypeMappings[0].PropertyMappings) { recurse(t, child, path + complex.Property.Name + "."); } } else if (item is ScalarPropertyMapping) { var scalar = item as ScalarPropertyMapping; tableMapping.PropertyMappings.Add(new PropertyMapping { ColumnName = scalar.Column.Name, DataType = scalar.Column.TypeName, DataTypeFull = GetFullTypeName(scalar), PropertyName = path + item.Property.Name, ForEntityType = t }); } }; Func <MappingFragment, Type> getClr = m => { return(GetClrTypeFromTypeMapping(metadata, objectItemCollection, m.TypeMapping as EntityTypeMapping)); }; if (mapping.EntityTypeMappings.Any(m => m.IsHierarchyMapping)) { var withConditions = mapping.EntityTypeMappings.Where(m => m.Fragments[0].Conditions.Any()).ToList(); tableMapping.TPHConfiguration = new TPHConfiguration { ColumnName = withConditions.First().Fragments[0].Conditions[0].Column.Name, Mappings = new Dictionary <Type, string>() }; foreach (var item in withConditions) { tableMapping.TPHConfiguration.Mappings.Add( getClr(item.Fragments[0]), ((ValueConditionMapping)item.Fragments[0].Conditions[0]).Value.ToString() ); } } foreach (var entityType in mapping.EntityTypeMappings) { foreach (var item in entityType.Fragments[0].PropertyMappings) { recurse(getClr(entityType.Fragments[0]), item, ""); } } //Inheriting propertymappings contains duplicates for id's. tableMapping.PropertyMappings = tableMapping.PropertyMappings.GroupBy(p => p.PropertyName) .Select(g => g.OrderByDescending(outer => g.Count(inner => inner.ForEntityType.IsSubclassOf(outer.ForEntityType))).First()) .ToList(); foreach (var item in tableMapping.PropertyMappings) { if ((mappingToLookAt.EntityType ?? mappingToLookAt.IsOfEntityTypes[0]).KeyProperties.Any(p => p.Name == item.PropertyName)) { item.IsPrimaryKey = true; } } } }
/// <summary> /// Initializes an instance of the EfMapping class /// </summary> /// <param name="db">The context to get the mapping from</param> public EfMapping(DbContext db) { this.TypeMappings = new Dictionary <Type, TypeMapping>(); var metadata = ((IObjectContextAdapter)db).ObjectContext.MetadataWorkspace; // Conceptual part of the model has info about the shape of our entity classes var conceptualContainer = metadata.GetItems <EntityContainer>(DataSpace.CSpace).Single(); // Storage part of the model has info about the shape of our tables var storeContainer = metadata.GetItems <EntityContainer>(DataSpace.SSpace).Single(); // Object part of the model that contains info about the actual CLR types var objectItemCollection = ((ObjectItemCollection)metadata.GetItemCollection(DataSpace.OSpace)); // Mapping part of model is not public, so we need to write to xml and use 'LINQ to XML' var edmx = GetEdmx(db); // Loop thru each entity type in the model foreach (var set in conceptualContainer.BaseEntitySets.OfType <EntitySet>()) { var typeMapping = new TypeMapping { TableMappings = new List <TableMapping>(), EntityType = GetClrType(metadata, objectItemCollection, set) }; this.TypeMappings.Add(typeMapping.EntityType, typeMapping); // Get the mapping fragments for this type // (types may have mutliple fragments if 'Entity Splitting' is used) var mappingFragments = edmx .Descendants() .First(e => e.Name.LocalName == "EntityTypeMapping" && (e.Attribute("TypeName").Value == set.ElementType.FullName || e.Attribute("TypeName").Value == string.Format("IsTypeOf({0})", set.ElementType.FullName))) .Descendants() .Where(e => e.Name.LocalName == "MappingFragment"); foreach (var mapping in mappingFragments) { var tableMapping = new TableMapping { PropertyMappings = new List <PropertyMapping>() }; typeMapping.TableMappings.Add(tableMapping); // Find the table that this fragment maps to var storeset = mapping.Attribute("StoreEntitySet").Value; var store = storeContainer .BaseEntitySets.OfType <EntitySet>() .Single(s => s.Name == storeset); tableMapping.TableName = (string)store.MetadataProperties["Table"].Value; tableMapping.Schema = (string)store.MetadataProperties["Schema"].Value; // Find the property-to-column mappings var propertyMappings = mapping .Descendants() .Where(e => e.Name.LocalName == "ScalarProperty"); foreach (var propertyMapping in propertyMappings) { var propertyName = GetFullName(propertyMapping); var columnName = propertyMapping.Attribute("ColumnName").Value; tableMapping.PropertyMappings.Add(new PropertyMapping { PropertyName = propertyName, ColumnName = columnName }); } } } }
/// <summary> /// Initializes an instance of the EfMapping class /// </summary> /// <param name="db">The context to get the mapping from</param> public EfMapping(DbContext db) { this.TypeMappings = new Dictionary<Type, TypeMapping>(); var metadata = ((IObjectContextAdapter)db).ObjectContext.MetadataWorkspace; //EF61Test(metadata); // Conceptual part of the model has info about the shape of our entity classes var conceptualContainer = metadata.GetItems<EntityContainer>(DataSpace.CSpace).Single(); // Storage part of the model has info about the shape of our tables var storeContainer = metadata.GetItems<EntityContainer>(DataSpace.SSpace).Single(); // Object part of the model that contains info about the actual CLR types var objectItemCollection = ((ObjectItemCollection)metadata.GetItemCollection(DataSpace.OSpace)); // Loop thru each entity type in the model foreach (var set in conceptualContainer.BaseEntitySets.OfType<EntitySet>()) { // Find the mapping between conceptual and storage model for this entity set var mapping = metadata.GetItems<EntityContainerMapping>(DataSpace.CSSpace) .Single() .EntitySetMappings .Single(s => s.EntitySet == set); var typeMapping = new TypeMapping { TableMappings = new List<TableMapping>(), EntityType = GetClrType(metadata, objectItemCollection, set) }; this.TypeMappings.Add(typeMapping.EntityType, typeMapping); var tableMapping = new TableMapping { PropertyMappings = new List<PropertyMapping>(), }; var mappingToLookAt = mapping.EntityTypeMappings.FirstOrDefault(m => m.IsHierarchyMapping) ?? mapping.EntityTypeMappings.First(); tableMapping.Schema = mappingToLookAt.Fragments[0].StoreEntitySet.Schema; tableMapping.TableName = mappingToLookAt.Fragments[0].StoreEntitySet.Table ?? mappingToLookAt.Fragments[0].StoreEntitySet.Name; typeMapping.TableMappings.Add(tableMapping); Action<Type, System.Data.Entity.Core.Mapping.PropertyMapping, string> recurse = null; recurse = (t, item, path) => { if (item is ComplexPropertyMapping) { var complex = item as ComplexPropertyMapping; foreach (var child in complex.TypeMappings[0].PropertyMappings) { recurse(t, child, path + complex.Property.Name + "."); } } else if (item is ScalarPropertyMapping) { var scalar = item as ScalarPropertyMapping; tableMapping.PropertyMappings.Add(new PropertyMapping { ColumnName = scalar.Column.Name, DataType = scalar.Column.TypeName, DataTypeFull = GetFullTypeName(scalar), PropertyName = path + item.Property.Name, ForEntityType = t }); } }; Func<MappingFragment, Type> getClr = m => { return GetClrTypeFromTypeMapping(metadata, objectItemCollection, m.TypeMapping as EntityTypeMapping); }; if (mapping.EntityTypeMappings.Any(m => m.IsHierarchyMapping)) { var withConditions = mapping.EntityTypeMappings.Where(m => m.Fragments[0].Conditions.Any()).ToList(); tableMapping.TPHConfiguration = new TPHConfiguration { ColumnName = withConditions.First().Fragments[0].Conditions[0].Column.Name, Mappings = new Dictionary<Type, string>() }; foreach (var item in withConditions) { tableMapping.TPHConfiguration.Mappings.Add( getClr(item.Fragments[0]), ((ValueConditionMapping)item.Fragments[0].Conditions[0]).Value.ToString() ); } } foreach (var entityType in mapping.EntityTypeMappings) { foreach (var item in entityType.Fragments[0].PropertyMappings) { recurse(getClr(entityType.Fragments[0]), item, ""); } } //Inheriting propertymappings contains duplicates for id's. tableMapping.PropertyMappings = tableMapping.PropertyMappings.GroupBy(p => p.PropertyName) .Select(g => g.OrderByDescending(outer => g.Count(inner => inner.ForEntityType.IsSubclassOf(outer.ForEntityType))).First()) .ToList(); foreach (var item in tableMapping.PropertyMappings) { if ((mappingToLookAt.EntityType ?? mappingToLookAt.IsOfEntityTypes[0]).KeyProperties.Any(p => p.Name == item.PropertyName)) { item.IsPrimaryKey = true; } } } }
/// <summary> /// 初始化Ef Mapping类的实例 /// </summary> /// <param name="db">The context to get the mapping from</param> public EfMapping(DbContext db) { this.TypeMappings = new Dictionary <Type, TypeMapping>(); var metadata = ((IObjectContextAdapter)db).ObjectContext.MetadataWorkspace; //EF61Test(元数据); // 模型的概念部分包含有关实体类形状的信息 var conceptualContainer = metadata.GetItems <EntityContainer>(DataSpace.CSpace).Single(); //模型的存储部分包含有关表格形状的信息 var storeContainer = metadata.GetItems <EntityContainer>(DataSpace.SSpace).Single(); // 模型的对象部分,包含有关实际CLR类型的信息 var objectItemCollection = ((ObjectItemCollection)metadata.GetItemCollection(DataSpace.OSpace)); // 循环遍历模型中的每个实体类型 foreach (var set in conceptualContainer.BaseEntitySets.OfType <EntitySet>()) { //查找此实体集的概念模型和存储模型之间的映射 var mapping = metadata.GetItems <EntityContainerMapping>(DataSpace.CSSpace) .Single() .EntitySetMappings .Single(s => s.EntitySet == set); var typeMapping = new TypeMapping { TableMappings = new List <TableMapping>(), EntityType = GetClrType(metadata, objectItemCollection, set) }; this.TypeMappings.Add(typeMapping.EntityType, typeMapping); var tableMapping = new TableMapping { PropertyMappings = new List <PropertyMapping>(), }; var mappingToLookAt = mapping.EntityTypeMappings.FirstOrDefault(m => m.IsHierarchyMapping) ?? mapping.EntityTypeMappings.First(); tableMapping.Schema = mappingToLookAt.Fragments[0].StoreEntitySet.Schema; tableMapping.TableName = mappingToLookAt.Fragments[0].StoreEntitySet.Table ?? mappingToLookAt.Fragments[0].StoreEntitySet.Name; typeMapping.TableMappings.Add(tableMapping); #pragma warning disable IDE0039 // 使用本地函数 Action <Type, System.Data.Entity.Core.Mapping.PropertyMapping, string> recurse = null; #pragma warning restore IDE0039 // 使用本地函数 recurse = (t, item, path) => { if (item is ComplexPropertyMapping) { var complex = item as ComplexPropertyMapping; foreach (var child in complex.TypeMappings[0].PropertyMappings) { recurse(t, child, path + complex.Property.Name + "."); } } else if (item is ScalarPropertyMapping) { var scalar = item as ScalarPropertyMapping; tableMapping.PropertyMappings.Add(new PropertyMapping { ColumnName = scalar.Column.Name, DataType = scalar.Column.TypeName, DataTypeFull = GetFullTypeName(scalar), PropertyName = path + item.Property.Name, ForEntityType = t }); } }; #pragma warning disable IDE0039 // 使用本地函数 Func <MappingFragment, Type> getClr = m => #pragma warning restore IDE0039 // 使用本地函数 { return(GetClrTypeFromTypeMapping(metadata, objectItemCollection, m.TypeMapping as EntityTypeMapping)); }; if (mapping.EntityTypeMappings.Any(m => m.IsHierarchyMapping)) { var withConditions = mapping.EntityTypeMappings.Where(m => m.Fragments[0].Conditions.Any()).ToList(); tableMapping.TPHConfiguration = new TPHConfiguration { ColumnName = withConditions.First().Fragments[0].Conditions[0].Column.Name, Mappings = new Dictionary <Type, string>() }; foreach (var item in withConditions) { tableMapping.TPHConfiguration.Mappings.Add( getClr(item.Fragments[0]), ((ValueConditionMapping)item.Fragments[0].Conditions[0]).Value.ToString() ); } } foreach (var entityType in mapping.EntityTypeMappings) { foreach (var item in entityType.Fragments[0].PropertyMappings) { recurse(getClr(entityType.Fragments[0]), item, ""); } } //Inheriting propertymappings contains duplicates for id's. tableMapping.PropertyMappings = tableMapping.PropertyMappings.GroupBy(p => p.PropertyName) .Select(g => g.OrderByDescending(outer => g.Count(inner => inner.ForEntityType.IsSubclassOf(outer.ForEntityType))).First()) .ToList(); foreach (var item in tableMapping.PropertyMappings) { if ((mappingToLookAt.EntityType ?? mappingToLookAt.IsOfEntityTypes[0]).KeyProperties.Any(p => p.Name == item.PropertyName)) { item.IsPrimaryKey = true; } } } }