// patch up the base type for all entities that don't have any yet. internal void DiscoverInheritanceRelationships() { Dictionary <Type, EntityTypeConfiguration> entityMap = StructuralTypes.OfType <EntityTypeConfiguration>().ToDictionary(e => e.ClrType); foreach (EntityTypeConfiguration entity in StructuralTypes.OfType <EntityTypeConfiguration>().Where(e => !e.BaseTypeConfigured)) { Type baseClrType = entity.ClrType.BaseType; while (baseClrType != null) { // see if we there is an entity that we know mapping to this clr types base type. EntityTypeConfiguration baseEntityType; if (entityMap.TryGetValue(baseClrType, out baseEntityType)) { RemoveBaseTypeProperties(entity, baseEntityType); // disable derived type key check if we are building a model for query composition. if (_isQueryCompositionMode) { // modifying the collection in the iterator, hence the ToArray(). foreach (PrimitivePropertyConfiguration keyProperty in entity.Keys.ToArray()) { entity.RemoveKey(keyProperty); } } entity.DerivesFrom(baseEntityType); break; } baseClrType = baseClrType.BaseType; } } }
private void ApplyForeignKeyConventions() { ForeignKeyAttributeConvention foreignKeyAttributeConvention = new ForeignKeyAttributeConvention(); ForeignKeyDiscoveryConvention foreignKeyDiscoveryConvention = new ForeignKeyDiscoveryConvention(); ActionOnDeleteAttributeConvention actionOnDeleteConvention = new ActionOnDeleteAttributeConvention(); foreach (EntityTypeConfiguration edmType in StructuralTypes.OfType <EntityTypeConfiguration>()) { foreach (PropertyConfiguration property in edmType.Properties) { // ForeignKeyDiscoveryConvention has to run after ForeignKeyAttributeConvention foreignKeyAttributeConvention.Apply(property, edmType, this); foreignKeyDiscoveryConvention.Apply(property, edmType, this); actionOnDeleteConvention.Apply(property, edmType, this); } } }
// patch up the base type for all entities that don't have any yet. internal void DiscoverInheritanceRelationships() { Dictionary <Type, EntityTypeConfiguration> entityMap = StructuralTypes.OfType <EntityTypeConfiguration>().ToDictionary(e => e.ClrType); foreach (EntityTypeConfiguration entity in StructuralTypes.OfType <EntityTypeConfiguration>().Where(e => !e.BaseTypeConfigured).ToArray()) { Type baseClrType = entity.ClrType.BaseType; while (baseClrType != null) { // see if we there is an entity that we know mapping to this clr types base type. EntityTypeConfiguration baseEntityType; if (entityMap.TryGetValue(baseClrType, out baseEntityType)) { RemoveBaseTypeProperties(entity, baseEntityType); entity.DerivesFrom(baseEntityType); break; } baseClrType = baseClrType.BaseType; } } }
private void ReconfigureEntityTypesAsComplexType(EntityTypeConfiguration[] misconfiguredEntityTypes) { IList <EntityTypeConfiguration> actualEntityTypes = StructuralTypes.OfType <EntityTypeConfiguration>() .Where(entity => entity.Keys().Any()) .Concat(_explicitlyAddedTypes.OfType <EntityTypeConfiguration>()) .Except(misconfiguredEntityTypes) .ToList(); HashSet <EntityTypeConfiguration> visitedEntityType = new HashSet <EntityTypeConfiguration>(); foreach (EntityTypeConfiguration misconfiguredEntityType in misconfiguredEntityTypes) { if (visitedEntityType.Contains(misconfiguredEntityType)) { continue; } // If one of the base types is already configured as entity type, we should keep this type as entity type. IEnumerable <EntityTypeConfiguration> basedTypes = misconfiguredEntityType .BaseTypes().OfType <EntityTypeConfiguration>(); if (actualEntityTypes.Any(e => basedTypes.Any(a => a.ClrType == e.ClrType))) { visitedEntityType.Add(misconfiguredEntityType); continue; } // Make sure to remove current type and all the derived types IList <EntityTypeConfiguration> thisAndDerivedTypes = this.DerivedTypes(misconfiguredEntityType) .Concat(new[] { misconfiguredEntityType }).OfType <EntityTypeConfiguration>().ToList(); foreach (EntityTypeConfiguration subEnityType in thisAndDerivedTypes) { if (actualEntityTypes.Any(e => e.ClrType == subEnityType.ClrType)) { throw Error.InvalidOperation(SRResources.CannotReconfigEntityTypeAsComplexType, misconfiguredEntityType.ClrType.FullName, subEnityType.ClrType.FullName); } RemoveStructuralType(subEnityType.ClrType); } // this is a wrongly inferred type. so just ignore any pending configuration from it. AddComplexType(misconfiguredEntityType.ClrType); foreach (EntityTypeConfiguration subEnityType in thisAndDerivedTypes) { visitedEntityType.Add(subEnityType); // go through all structural types to remove all properties defined by this mis-configed type. IList <StructuralTypeConfiguration> allTypes = StructuralTypes.ToList(); foreach (StructuralTypeConfiguration structuralToBePatched in allTypes) { NavigationPropertyConfiguration[] propertiesToBeRemoved = structuralToBePatched .NavigationProperties .Where(navigationProperty => navigationProperty.RelatedClrType == subEnityType.ClrType) .ToArray(); foreach (NavigationPropertyConfiguration propertyToBeRemoved in propertiesToBeRemoved) { string propertyNameAlias = propertyToBeRemoved.Name; PropertyConfiguration propertyConfiguration; structuralToBePatched.RemoveProperty(propertyToBeRemoved.PropertyInfo); if (propertyToBeRemoved.Multiplicity == EdmMultiplicity.Many) { propertyConfiguration = structuralToBePatched.AddCollectionProperty(propertyToBeRemoved.PropertyInfo); } else { propertyConfiguration = structuralToBePatched.AddComplexProperty(propertyToBeRemoved.PropertyInfo); } Contract.Assert(propertyToBeRemoved.AddedExplicitly == false); // The newly added property must be marked as added implicitly. This can make sure the property // conventions can be re-applied to the new property. propertyConfiguration.AddedExplicitly = false; ReapplyPropertyConvention(propertyConfiguration, structuralToBePatched); propertyConfiguration.Name = propertyNameAlias; } } } } }