Esempio n. 1
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;
                    }
                }
            }
        }