/// <summary> /// This API supports the Entity Framework Core infrastructure and is not intended to be used /// directly from your code. This API may change or be removed in future releases. /// </summary> public virtual InternalModelBuilder Apply(InternalModelBuilder modelBuilder) { foreach (var entityType in modelBuilder.Metadata.GetEntityTypes()) { foreach (var foreignKey in entityType.GetDeclaredForeignKeys().Where(fk => fk.GetForeignKeyPropertiesConfigurationSource() == null)) { var foreignKeyProperties = FindCandidateForeignKeyProperties(foreignKey, onDependent: true); if (foreignKeyProperties != null) { var conflictingForeignKey = foreignKey.DeclaringEntityType.FindForeignKeysInHierarchy(foreignKeyProperties) .FirstOrDefault(fk => fk != foreignKey && ConfigurationSource.Convention.Overrides(fk.GetForeignKeyPropertiesConfigurationSource())); if (conflictingForeignKey != null) { throw new InvalidOperationException(CoreStrings.AmbiguousForeignKeyPropertyCandidates( conflictingForeignKey.DeclaringEntityType.DisplayName() + (conflictingForeignKey.DependentToPrincipal == null ? "" : "." + conflictingForeignKey.DependentToPrincipal.Name), conflictingForeignKey.PrincipalEntityType.DisplayName() + (conflictingForeignKey.PrincipalToDependent == null ? "" : "." + conflictingForeignKey.PrincipalToDependent.Name), foreignKey.DeclaringEntityType.DisplayName() + (foreignKey.DependentToPrincipal == null ? "" : "." + foreignKey.DependentToPrincipal.Name), foreignKey.PrincipalEntityType.DisplayName() + (foreignKey.PrincipalToDependent == null ? "" : "." + foreignKey.PrincipalToDependent.Name), Property.Format(foreignKeyProperties))); } } } } return(modelBuilder); }
public virtual void ProcessModelFinalizing( IConventionModelBuilder modelBuilder, IConventionContext <IConventionModelBuilder> context) { foreach (var entityType in modelBuilder.Metadata.GetEntityTypes()) { var conflictingFkFound = false; foreach (var foreignKey in entityType.GetDeclaredForeignKeys().Where(fk => fk.GetPropertiesConfigurationSource() == null)) { var foreignKeyProperties = FindCandidateForeignKeyProperties(foreignKey, onDependent: true); if (foreignKeyProperties != null) { var conflictingForeignKey = foreignKey.DeclaringEntityType.FindForeignKeys(foreignKeyProperties).Concat( foreignKey.DeclaringEntityType.GetDerivedTypes() .SelectMany(et => et.FindDeclaredForeignKeys(foreignKeyProperties))) .FirstOrDefault( fk => fk != foreignKey && ConfigurationSource.Convention.Overrides(fk.GetPropertiesConfigurationSource())); if (conflictingForeignKey != null) { throw new InvalidOperationException( CoreStrings.AmbiguousForeignKeyPropertyCandidates( conflictingForeignKey.DeclaringEntityType.DisplayName() + (conflictingForeignKey.DependentToPrincipal == null ? "" : "." + conflictingForeignKey.DependentToPrincipal.Name), conflictingForeignKey.PrincipalEntityType.DisplayName() + (conflictingForeignKey.PrincipalToDependent == null ? "" : "." + conflictingForeignKey.PrincipalToDependent.Name), foreignKey.DeclaringEntityType.DisplayName() + (foreignKey.DependentToPrincipal == null ? "" : "." + foreignKey.DependentToPrincipal.Name), foreignKey.PrincipalEntityType.DisplayName() + (foreignKey.PrincipalToDependent == null ? "" : "." + foreignKey.PrincipalToDependent.Name), foreignKeyProperties.Format())); } } if (conflictingFkFound) { continue; } if (HasUniquifiedProperties(foreignKey)) { var conflictingFk = entityType.GetDeclaredForeignKeys().FirstOrDefault( otherForeignKey => otherForeignKey != foreignKey && otherForeignKey.PrincipalEntityType == foreignKey.PrincipalEntityType && otherForeignKey.GetPropertiesConfigurationSource() == null); if (conflictingFk != null) { conflictingFkFound = true; Dependencies.Logger.ConflictingShadowForeignKeysWarning(conflictingFk); } } } } }
public void Throws_on_ambiguous_relationship() { DependentType.Property(DependentEntity.PrincipalEntityPeEKaYProperty, ConfigurationSource.Convention); DependentType.Property(DependentEntity.PrincipalEntityIDProperty, ConfigurationSource.Convention); DependentType.Property(DependentEntity.PeEKaYProperty, ConfigurationSource.Convention); var relationshipBuilder = DependentType.Relationship( PrincipalType, "SomeNav", null, ConfigurationSource.Convention); var convention = new ForeignKeyPropertyDiscoveryConvention(); var newRelationshipBuilder = convention.Apply(relationshipBuilder); Assert.NotSame(relationshipBuilder, newRelationshipBuilder); var otherRelationshipBuilder = DependentType.Relationship( PrincipalType, (string)null, null, ConfigurationSource.Convention); var otherNewRelationshipBuilder = convention.Apply(otherRelationshipBuilder); Assert.Same(otherRelationshipBuilder, otherNewRelationshipBuilder); Assert.Equal( CoreStrings.AmbiguousForeignKeyPropertyCandidates( nameof(DependentEntity) + ".SomeNav", nameof(PrincipalEntity), nameof(DependentEntity), nameof(PrincipalEntity), "{'" + nameof(DependentEntity.PrincipalEntityPeEKaY) + "'}"), Assert.Throws <InvalidOperationException>(() => convention.Apply(DependentType.Metadata.Model.Builder)).Message); newRelationshipBuilder.Metadata.UpdateForeignKeyPropertiesConfigurationSource(ConfigurationSource.Explicit); convention.Apply(DependentType.Metadata.Model.Builder); }