/// <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;
                    }
                }
            }
        }
Esempio n. 2
0
        /// <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;
                    }
                }
            }
        }
Esempio n. 4
0
        /// <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;
                    }
                }
            }
        }