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); }
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); }