private static void CreateRelationships( IReadOnlyList <RelationshipCandidate> relationshipCandidates, InternalEntityTypeBuilder entityTypeBuilder) { foreach (var relationshipCandidate in relationshipCandidates) { Debug.Assert(relationshipCandidate.NavigationProperties.Count > 0); if ((relationshipCandidate.NavigationProperties.Count > 1 && relationshipCandidate.InverseProperties.Count > 0) || relationshipCandidate.InverseProperties.Count > 1) { foreach (var navigationProperty in relationshipCandidate.NavigationProperties) { var existingForeignKey = entityTypeBuilder.Metadata.FindDeclaredNavigation(navigationProperty.Name)?.ForeignKey; existingForeignKey?.DeclaringEntityType.Builder .RemoveForeignKey(existingForeignKey, ConfigurationSource.Convention); } foreach (var inverseProperty in relationshipCandidate.InverseProperties) { var existingForeignKey = relationshipCandidate.TargetTypeBuilder.Metadata .FindDeclaredNavigation(inverseProperty.Name)?.ForeignKey; existingForeignKey?.DeclaringEntityType.Builder .RemoveForeignKey(existingForeignKey, ConfigurationSource.Convention); } continue; } foreach (var navigation in relationshipCandidate.NavigationProperties) { var inverse = relationshipCandidate.InverseProperties.SingleOrDefault(); if (inverse == null) { entityTypeBuilder.Navigation( relationshipCandidate.TargetTypeBuilder, navigation, ConfigurationSource.Convention); } else { entityTypeBuilder.Relationship( relationshipCandidate.TargetTypeBuilder, navigation, inverse, ConfigurationSource.Convention); } } } }
private void CreateRelationships( IReadOnlyList <RelationshipCandidate> relationshipCandidates, InternalEntityTypeBuilder entityTypeBuilder) { var unusedEntityTypes = new List <EntityType>(); foreach (var relationshipCandidate in relationshipCandidates) { Debug.Assert(relationshipCandidate.NavigationProperties.Count > 0); var entityType = entityTypeBuilder.Metadata; var targetEntityType = relationshipCandidate.TargetTypeBuilder.Metadata; var isAmbiguousOnBase = (entityType.BaseType != null && HasAmbiguousNavigationsTo( entityType.BaseType, targetEntityType.ClrType)) || (targetEntityType.BaseType != null && HasAmbiguousNavigationsTo( targetEntityType.BaseType, entityType.ClrType)); if ((relationshipCandidate.NavigationProperties.Count > 1 && relationshipCandidate.InverseProperties.Count > 0) || relationshipCandidate.InverseProperties.Count > 1 || isAmbiguousOnBase) { if (!isAmbiguousOnBase) { AddAmbiguous(entityTypeBuilder, relationshipCandidate.NavigationProperties, targetEntityType.ClrType); AddAmbiguous(relationshipCandidate.TargetTypeBuilder, relationshipCandidate.InverseProperties, entityType.ClrType); } foreach (var navigationProperty in relationshipCandidate.NavigationProperties) { var existingForeignKey = entityType.FindDeclaredNavigation(navigationProperty.Name)?.ForeignKey; existingForeignKey?.DeclaringEntityType.Builder .RemoveForeignKey(existingForeignKey, ConfigurationSource.Convention); } foreach (var inverseProperty in relationshipCandidate.InverseProperties) { var existingForeignKey = targetEntityType.FindDeclaredNavigation(inverseProperty.Name)?.ForeignKey; existingForeignKey?.DeclaringEntityType.Builder .RemoveForeignKey(existingForeignKey, ConfigurationSource.Convention); } unusedEntityTypes.Add(targetEntityType); continue; } foreach (var navigation in relationshipCandidate.NavigationProperties) { if (targetEntityType.Builder == null) { continue; } if (InversePropertyAttributeConvention.IsAmbiguous(entityType, navigation, targetEntityType)) { unusedEntityTypes.Add(targetEntityType); continue; } var inverse = relationshipCandidate.InverseProperties.SingleOrDefault(); if (inverse == null) { entityTypeBuilder.Navigation( relationshipCandidate.TargetTypeBuilder, navigation, ConfigurationSource.Convention); } else { if (InversePropertyAttributeConvention.IsAmbiguous(targetEntityType, inverse, entityType)) { unusedEntityTypes.Add(targetEntityType); continue; } entityTypeBuilder.Relationship( targetEntityType.Builder, navigation, inverse, ConfigurationSource.Convention); } } } foreach (var unusedEntityType in unusedEntityTypes) { if (unusedEntityType.HasDelegatedIdentity() && unusedEntityType.DefiningEntityType.FindNavigation(unusedEntityType.DefiningNavigationName) == null) { entityTypeBuilder.ModelBuilder. RemoveDelegatedIdentityEntityType(unusedEntityType, ConfigurationSource.Convention); } } }
private static void CreateRelationships( IEnumerable <RelationshipCandidate> relationshipCandidates, InternalEntityTypeBuilder entityTypeBuilder) { var unusedEntityTypes = new List <EntityType>(); foreach (var relationshipCandidate in relationshipCandidates) { var entityType = entityTypeBuilder.Metadata; var targetEntityType = relationshipCandidate.TargetTypeBuilder.Metadata; var isAmbiguousOnBase = entityType.BaseType != null && HasAmbiguousNavigationsTo( entityType.BaseType, targetEntityType.ClrType) || targetEntityType.BaseType != null && HasAmbiguousNavigationsTo( targetEntityType.BaseType, entityType.ClrType); if (relationshipCandidate.NavigationProperties.Count > 1 && relationshipCandidate.InverseProperties.Count > 0 || relationshipCandidate.InverseProperties.Count > 1 || isAmbiguousOnBase) { if (!isAmbiguousOnBase) { AddAmbiguous(entityTypeBuilder, relationshipCandidate.NavigationProperties, targetEntityType.ClrType); AddAmbiguous(targetEntityType.Builder, relationshipCandidate.InverseProperties, entityType.ClrType); } foreach (var navigationProperty in relationshipCandidate.NavigationProperties) { var existingForeignKey = entityType.FindDeclaredNavigation(navigationProperty.Name)?.ForeignKey; existingForeignKey?.DeclaringEntityType.Builder .RemoveForeignKey(existingForeignKey, ConfigurationSource.Convention); } foreach (var inverseProperty in relationshipCandidate.InverseProperties) { var existingForeignKey = targetEntityType.FindDeclaredNavigation(inverseProperty.Name)?.ForeignKey; existingForeignKey?.DeclaringEntityType.Builder .RemoveForeignKey(existingForeignKey, ConfigurationSource.Convention); } unusedEntityTypes.Add(targetEntityType); continue; } foreach (var navigation in relationshipCandidate.NavigationProperties) { if (targetEntityType.Builder == null) { continue; } if (InversePropertyAttributeConvention.IsAmbiguous(entityType, navigation, targetEntityType)) { unusedEntityTypes.Add(targetEntityType); continue; } var inverse = relationshipCandidate.InverseProperties.SingleOrDefault(); if (inverse == null) { if (targetEntityType.DefiningNavigationName == navigation.Name && targetEntityType.DefiningEntityType == entityType && targetEntityType.Model.ShouldBeOwnedType(targetEntityType.ClrType)) { entityTypeBuilder.Owns( targetEntityType.ClrType, navigation, ConfigurationSource.Convention); } else { entityTypeBuilder.Navigation( targetEntityType.Builder, navigation, ConfigurationSource.Convention); } } else { if (InversePropertyAttributeConvention.IsAmbiguous(targetEntityType, inverse, entityType)) { unusedEntityTypes.Add(targetEntityType); continue; } if (targetEntityType.DefiningNavigationName == navigation.Name && targetEntityType.DefiningEntityType == entityType && targetEntityType.Model.ShouldBeOwnedType(targetEntityType.ClrType)) { entityTypeBuilder.Owns( targetEntityType.ClrType, navigation, inverse, ConfigurationSource.Convention); } else { entityTypeBuilder.Relationship( targetEntityType.Builder, navigation, inverse, ConfigurationSource.Convention); } } } if (relationshipCandidate.NavigationProperties.Count == 0) { foreach (var inverse in relationshipCandidate.InverseProperties) { if (targetEntityType.Builder == null) { continue; } if (InversePropertyAttributeConvention.IsAmbiguous(targetEntityType, inverse, entityType)) { unusedEntityTypes.Add(targetEntityType); continue; } targetEntityType.Builder.Navigation( entityTypeBuilder, inverse, ConfigurationSource.Convention); } } } foreach (var unusedEntityType in unusedEntityTypes) { if (unusedEntityType.HasDefiningNavigation() && unusedEntityType.DefiningEntityType.FindNavigation(unusedEntityType.DefiningNavigationName) == null) { entityTypeBuilder.ModelBuilder.RemoveEntityType(unusedEntityType, ConfigurationSource.Convention); } } }
private void CreateRelationships( IReadOnlyList <RelationshipCandidate> relationshipCandidates, InternalEntityTypeBuilder entityTypeBuilder) { foreach (var relationshipCandidate in relationshipCandidates) { Debug.Assert(relationshipCandidate.NavigationProperties.Count > 0); var isAmbiguousOnBase = (entityTypeBuilder.Metadata.BaseType != null && HasAmbiguousNavigationsTo( entityTypeBuilder.Metadata.BaseType, relationshipCandidate.TargetTypeBuilder.Metadata.ClrType)) || (relationshipCandidate.TargetTypeBuilder.Metadata.BaseType != null && HasAmbiguousNavigationsTo( relationshipCandidate.TargetTypeBuilder.Metadata.BaseType, entityTypeBuilder.Metadata.ClrType)); if ((relationshipCandidate.NavigationProperties.Count > 1 && relationshipCandidate.InverseProperties.Count > 0) || relationshipCandidate.InverseProperties.Count > 1 || isAmbiguousOnBase) { if (!isAmbiguousOnBase) { AddAmbiguous(entityTypeBuilder, relationshipCandidate.NavigationProperties, relationshipCandidate.TargetTypeBuilder.Metadata.ClrType); AddAmbiguous(relationshipCandidate.TargetTypeBuilder, relationshipCandidate.InverseProperties, entityTypeBuilder.Metadata.ClrType); } foreach (var navigationProperty in relationshipCandidate.NavigationProperties) { var existingForeignKey = entityTypeBuilder.Metadata.FindDeclaredNavigation(navigationProperty.Name)?.ForeignKey; existingForeignKey?.DeclaringEntityType.Builder .RemoveForeignKey(existingForeignKey, ConfigurationSource.Convention); } foreach (var inverseProperty in relationshipCandidate.InverseProperties) { var existingForeignKey = relationshipCandidate.TargetTypeBuilder.Metadata .FindDeclaredNavigation(inverseProperty.Name)?.ForeignKey; existingForeignKey?.DeclaringEntityType.Builder .RemoveForeignKey(existingForeignKey, ConfigurationSource.Convention); } continue; } foreach (var navigation in relationshipCandidate.NavigationProperties) { var inverse = relationshipCandidate.InverseProperties.SingleOrDefault(); if (inverse == null) { entityTypeBuilder.Navigation( relationshipCandidate.TargetTypeBuilder, navigation, ConfigurationSource.Convention); } else { entityTypeBuilder.Relationship( relationshipCandidate.TargetTypeBuilder, navigation, inverse, ConfigurationSource.Convention); } } } }