Esempio n. 1
0
        /// <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);
        }
Esempio n. 2
0
        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);
        }