Beispiel #1
0
        public void Configure(
            DbDatabaseMapping databaseMapping,
            ICollection <EntitySet> entitySets,
            DbProviderManifest providerManifest,
            EntityType entityType,
            ref EntityTypeMapping entityTypeMapping,
            bool isMappingAnyInheritedProperty,
            int configurationIndex,
            int configurationCount,
            IDictionary <string, object> commonAnnotations)
        {
            DebugCheck.NotNull(entityType);
            DebugCheck.NotNull(databaseMapping);
            DebugCheck.NotNull(providerManifest);

            var baseType        = (EntityType)entityType.BaseType;
            var isIdentityTable = baseType == null && configurationIndex == 0;

            var fragment = FindOrCreateTypeMappingFragment(
                databaseMapping, ref entityTypeMapping, configurationIndex, entityType, providerManifest);
            var  fromTable = fragment.Table;
            bool isTableSharing;
            var  toTable = FindOrCreateTargetTable(
                databaseMapping, fragment, entityType, fromTable, out isTableSharing);

            var isSharingTableWithBase = DiscoverIsSharingWithBase(databaseMapping, entityType, toTable);

            // Ensure all specified properties are the only ones present in this fragment and table
            var mappingsToContain = DiscoverAllMappingsToContain(
                databaseMapping, entityType, toTable, isSharingTableWithBase);

            // Validate that specified properties can be mapped
            var mappingsToMove = fragment.ColumnMappings.ToList();

            foreach (var propertyPath in mappingsToContain)
            {
                var propertyMapping = fragment.ColumnMappings.SingleOrDefault(
                    pm => pm.PropertyPath.SequenceEqual(propertyPath));

                if (propertyMapping == null)
                {
                    throw Error.EntityMappingConfiguration_DuplicateMappedProperty(
                              entityType.Name, propertyPath.ToString());
                }
                mappingsToMove.Remove(propertyMapping);
            }

            // Add table constraint if there are no inherited properties
            if (!isIdentityTable)
            {
                bool isSplitting;
                var  parentTable = FindParentTable(
                    databaseMapping,
                    fromTable,
                    entityTypeMapping,
                    toTable,
                    isMappingAnyInheritedProperty,
                    configurationIndex,
                    configurationCount,
                    out isSplitting);
                if (parentTable != null)
                {
                    DatabaseOperations.AddTypeConstraint(databaseMapping.Database, entityType, parentTable, toTable, isSplitting);
                }
            }

            // Update AssociationSetMappings (IAs) and FKs
            if (fromTable != toTable)
            {
                if (Properties == null)
                {
                    AssociationMappingOperations.MoveAllDeclaredAssociationSetMappings(
                        databaseMapping, entityType, fromTable, toTable, !isTableSharing);
                    ForeignKeyPrimitiveOperations.MoveAllDeclaredForeignKeyConstraintsForPrimaryKeyColumns(
                        entityType, fromTable, toTable);
                }
                if (isMappingAnyInheritedProperty)
                {
                    var baseTables =
                        databaseMapping.GetEntityTypeMappings(baseType)
                        .SelectMany(etm => etm.MappingFragments)
                        .Select(mf => mf.Table);

                    var associationMapping = databaseMapping.EntityContainerMappings
                                             .SelectMany(asm => asm.AssociationSetMappings)
                                             .FirstOrDefault(a => baseTables.Contains(a.Table) &&
                                                             (baseType == a.AssociationSet.ElementType.SourceEnd.GetEntityType() ||
                                                              baseType == a.AssociationSet.ElementType.TargetEnd.GetEntityType()));

                    if (associationMapping != null)
                    {
                        var associationType = associationMapping.AssociationSet.ElementType;

                        throw Error.EntityMappingConfiguration_TPCWithIAsOnNonLeafType(
                                  associationType.Name,
                                  associationType.SourceEnd.GetEntityType().Name,
                                  associationType.TargetEnd.GetEntityType().Name);
                    }

                    // With TPC, we need to move down FK constraints, even on PKs (except type mapping constraints that are not about associations)
                    ForeignKeyPrimitiveOperations.CopyAllForeignKeyConstraintsForPrimaryKeyColumns(
                        databaseMapping.Database, fromTable, toTable);
                }
            }

            if (mappingsToMove.Any())
            {
                EntityType extraTable = null;
                if (configurationIndex < configurationCount - 1)
                {
                    // Move all extra properties to a single new fragment
                    var anyPropertyMapping = mappingsToMove.First();

                    extraTable
                        = FindTableForTemporaryExtraPropertyMapping(
                              databaseMapping, entityType, fromTable, toTable, anyPropertyMapping);

                    var extraFragment
                        = EntityMappingOperations
                          .CreateTypeMappingFragment(entityTypeMapping, fragment, databaseMapping.Database.GetEntitySet(extraTable));

                    var requiresUpdate = extraTable != fromTable;

                    foreach (var pm in mappingsToMove)
                    {
                        // move the property mapping from toFragment to extraFragment
                        EntityMappingOperations.MovePropertyMapping(
                            databaseMapping, entitySets, fragment, extraFragment, pm, requiresUpdate, true);
                    }
                }
                else
                {
                    // Move each extra property mapping to a fragment refering to the table with the base mapping
                    EntityType unmappedTable = null;
                    foreach (var pm in mappingsToMove)
                    {
                        extraTable = FindTableForExtraPropertyMapping(
                            databaseMapping, entityType, fromTable, toTable, ref unmappedTable, pm);

                        var extraFragment =
                            entityTypeMapping.MappingFragments.SingleOrDefault(tmf => tmf.Table == extraTable);

                        if (extraFragment == null)
                        {
                            extraFragment
                                = EntityMappingOperations
                                  .CreateTypeMappingFragment(
                                      entityTypeMapping, fragment, databaseMapping.Database.GetEntitySet(extraTable));

                            extraFragment.SetIsUnmappedPropertiesFragment(true);
                        }

                        if (extraTable == fromTable)
                        {
                            // copy the default discriminator along with the properties
                            CopyDefaultDiscriminator(fragment, extraFragment);
                        }

                        var requiresUpdate = extraTable != fromTable;
                        EntityMappingOperations.MovePropertyMapping(
                            databaseMapping, entitySets, fragment, extraFragment, pm, requiresUpdate, true);
                    }
                }
            }

            // Ensure all property mappings refer to the table in the fragment
            // Uniquify: true if table sharing, false otherwise
            //           FK names should be uniquified
            //           declared properties are moved, inherited ones are copied (duplicated)
            EntityMappingOperations.UpdatePropertyMappings(
                databaseMapping, entitySets, fromTable, fragment, !isTableSharing);

            // Configure Conditions for the fragment
            ConfigureDefaultDiscriminator(entityType, fragment);
            ConfigureConditions(databaseMapping, entityType, fragment, providerManifest);

            // Ensure all conditions refer to columns on the table in the fragment
            EntityMappingOperations.UpdateConditions(databaseMapping.Database, fromTable, fragment);

            ForeignKeyPrimitiveOperations.UpdatePrincipalTables(
                databaseMapping, entityType, fromTable, toTable, isMappingAnyInheritedProperty);

            CleanupUnmappedArtifacts(databaseMapping, fromTable);
            CleanupUnmappedArtifacts(databaseMapping, toTable);

            ConfigureAnnotations(toTable, commonAnnotations);
            ConfigureAnnotations(toTable, _annotations);

            toTable.SetConfiguration(this);
        }
Beispiel #2
0
        public void Configure(
            DbDatabaseMapping databaseMapping,
            ICollection <EntitySet> entitySets,
            DbProviderManifest providerManifest,
            EntityType entityType,
            ref EntityTypeMapping entityTypeMapping,
            bool isMappingAnyInheritedProperty,
            int configurationIndex,
            int configurationCount,
            IDictionary <string, object> commonAnnotations)
        {
            EntityType                  baseType             = (EntityType)entityType.BaseType;
            bool                        flag                 = baseType == null && configurationIndex == 0;
            MappingFragment             typeMappingFragment1 = this.FindOrCreateTypeMappingFragment(databaseMapping, ref entityTypeMapping, configurationIndex, entityType, providerManifest);
            EntityType                  table                = typeMappingFragment1.Table;
            bool                        isTableSharing;
            EntityType                  createTargetTable      = this.FindOrCreateTargetTable(databaseMapping, typeMappingFragment1, entityType, table, out isTableSharing);
            bool                        isSharingTableWithBase = this.DiscoverIsSharingWithBase(databaseMapping, entityType, createTargetTable);
            HashSet <EdmPropertyPath>   contain = this.DiscoverAllMappingsToContain(databaseMapping, entityType, createTargetTable, isSharingTableWithBase);
            List <ColumnMappingBuilder> list    = typeMappingFragment1.ColumnMappings.ToList <ColumnMappingBuilder>();

            foreach (EdmPropertyPath edmPropertyPath in contain)
            {
                EdmPropertyPath      propertyPath         = edmPropertyPath;
                ColumnMappingBuilder columnMappingBuilder = typeMappingFragment1.ColumnMappings.SingleOrDefault <ColumnMappingBuilder>((Func <ColumnMappingBuilder, bool>)(pm => pm.PropertyPath.SequenceEqual <EdmProperty>((IEnumerable <EdmProperty>)propertyPath)));
                if (columnMappingBuilder == null)
                {
                    throw Error.EntityMappingConfiguration_DuplicateMappedProperty((object)entityType.Name, (object)propertyPath.ToString());
                }
                list.Remove(columnMappingBuilder);
            }
            if (!flag)
            {
                bool       isSplitting;
                EntityType parentTable = EntityMappingConfiguration.FindParentTable(databaseMapping, table, entityTypeMapping, createTargetTable, isMappingAnyInheritedProperty, configurationIndex, configurationCount, out isSplitting);
                if (parentTable != null)
                {
                    DatabaseOperations.AddTypeConstraint(databaseMapping.Database, entityType, parentTable, createTargetTable, isSplitting);
                }
            }
            if (table != createTargetTable)
            {
                if (this.Properties == null)
                {
                    AssociationMappingOperations.MoveAllDeclaredAssociationSetMappings(databaseMapping, entityType, table, createTargetTable, !isTableSharing);
                    ForeignKeyPrimitiveOperations.MoveAllDeclaredForeignKeyConstraintsForPrimaryKeyColumns(entityType, table, createTargetTable);
                }
                if (isMappingAnyInheritedProperty)
                {
                    IEnumerable <EntityType> baseTables            = databaseMapping.GetEntityTypeMappings(baseType).SelectMany <EntityTypeMapping, MappingFragment>((Func <EntityTypeMapping, IEnumerable <MappingFragment> >)(etm => (IEnumerable <MappingFragment>)etm.MappingFragments)).Select <MappingFragment, EntityType>((Func <MappingFragment, EntityType>)(mf => mf.Table));
                    AssociationSetMapping    associationSetMapping = databaseMapping.EntityContainerMappings.SelectMany <EntityContainerMapping, AssociationSetMapping>((Func <EntityContainerMapping, IEnumerable <AssociationSetMapping> >)(asm => asm.AssociationSetMappings)).FirstOrDefault <AssociationSetMapping>((Func <AssociationSetMapping, bool>)(a =>
                    {
                        if (!baseTables.Contains <EntityType>(a.Table))
                        {
                            return(false);
                        }
                        if (baseType != a.AssociationSet.ElementType.SourceEnd.GetEntityType())
                        {
                            return(baseType == a.AssociationSet.ElementType.TargetEnd.GetEntityType());
                        }
                        return(true);
                    }));
                    if (associationSetMapping != null)
                    {
                        AssociationType elementType = associationSetMapping.AssociationSet.ElementType;
                        throw Error.EntityMappingConfiguration_TPCWithIAsOnNonLeafType((object)elementType.Name, (object)elementType.SourceEnd.GetEntityType().Name, (object)elementType.TargetEnd.GetEntityType().Name);
                    }
                    ForeignKeyPrimitiveOperations.CopyAllForeignKeyConstraintsForPrimaryKeyColumns(databaseMapping.Database, table, createTargetTable);
                }
            }
            if (list.Any <ColumnMappingBuilder>())
            {
                EntityType extraTable = (EntityType)null;
                if (configurationIndex < configurationCount - 1)
                {
                    ColumnMappingBuilder pm = list.First <ColumnMappingBuilder>();
                    extraTable = EntityMappingConfiguration.FindTableForTemporaryExtraPropertyMapping(databaseMapping, entityType, table, createTargetTable, pm);
                    MappingFragment typeMappingFragment2 = EntityMappingOperations.CreateTypeMappingFragment(entityTypeMapping, typeMappingFragment1, databaseMapping.Database.GetEntitySet(extraTable));
                    bool            requiresUpdate       = extraTable != table;
                    foreach (ColumnMappingBuilder propertyMappingBuilder in list)
                    {
                        EntityMappingOperations.MovePropertyMapping(databaseMapping, (IEnumerable <EntitySet>)entitySets, typeMappingFragment1, typeMappingFragment2, propertyMappingBuilder, requiresUpdate, true);
                    }
                }
                else
                {
                    EntityType unmappedTable = (EntityType)null;
                    foreach (ColumnMappingBuilder columnMappingBuilder in list)
                    {
                        extraTable = EntityMappingConfiguration.FindTableForExtraPropertyMapping(databaseMapping, entityType, table, createTargetTable, ref unmappedTable, columnMappingBuilder);
                        MappingFragment mappingFragment = entityTypeMapping.MappingFragments.SingleOrDefault <MappingFragment>((Func <MappingFragment, bool>)(tmf => tmf.Table == extraTable));
                        if (mappingFragment == null)
                        {
                            mappingFragment = EntityMappingOperations.CreateTypeMappingFragment(entityTypeMapping, typeMappingFragment1, databaseMapping.Database.GetEntitySet(extraTable));
                            mappingFragment.SetIsUnmappedPropertiesFragment(true);
                        }
                        if (extraTable == table)
                        {
                            EntityMappingConfiguration.CopyDefaultDiscriminator(typeMappingFragment1, mappingFragment);
                        }
                        bool requiresUpdate = extraTable != table;
                        EntityMappingOperations.MovePropertyMapping(databaseMapping, (IEnumerable <EntitySet>)entitySets, typeMappingFragment1, mappingFragment, columnMappingBuilder, requiresUpdate, true);
                    }
                }
            }
            EntityMappingOperations.UpdatePropertyMappings(databaseMapping, (IEnumerable <EntitySet>)entitySets, table, typeMappingFragment1, !isTableSharing);
            this.ConfigureDefaultDiscriminator(entityType, typeMappingFragment1);
            this.ConfigureConditions(databaseMapping, entityType, typeMappingFragment1, providerManifest);
            EntityMappingOperations.UpdateConditions(databaseMapping.Database, table, typeMappingFragment1);
            ForeignKeyPrimitiveOperations.UpdatePrincipalTables(databaseMapping, entityType, table, createTargetTable, isMappingAnyInheritedProperty);
            EntityMappingConfiguration.CleanupUnmappedArtifacts(databaseMapping, table);
            EntityMappingConfiguration.CleanupUnmappedArtifacts(databaseMapping, createTargetTable);
            EntityMappingConfiguration.ConfigureAnnotations((EdmType)createTargetTable, commonAnnotations);
            EntityMappingConfiguration.ConfigureAnnotations((EdmType)createTargetTable, this._annotations);
            createTargetTable.SetConfiguration((object)this);
        }