示例#1
0
    /// <summary>
    ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to
    ///     the same compatibility standards as public APIs. It may be changed or removed without notice in
    ///     any release. You should only use it directly in your code with extreme caution and knowing that
    ///     doing so can result in application failures when updating to a new Entity Framework Core release.
    /// </summary>
    public virtual bool CanSetForeignKey(ForeignKey?foreignKey, ConfigurationSource?configurationSource)
    {
        if (!configurationSource.Overrides(Metadata.GetForeignKeyConfigurationSource()))
        {
            return(Equals(Metadata.ForeignKey, foreignKey));
        }

        if (foreignKey == null)
        {
            return(true);
        }

        if (Metadata.DeclaringEntityType
            != (Metadata.IsOnDependent ? foreignKey.DeclaringEntityType : foreignKey.PrincipalEntityType))
        {
            return(false);
        }

        if (Metadata.Inverse?.JoinEntityType == null)
        {
            return(true);
        }

        return(Metadata.Inverse.JoinEntityType
               == (Metadata.IsOnDependent ? foreignKey.PrincipalEntityType : foreignKey.DeclaringEntityType) ||
               Metadata.Inverse.Builder.CanSetForeignKey(null, configurationSource));
    }
示例#2
0
    /// <summary>
    ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to
    ///     the same compatibility standards as public APIs. It may be changed or removed without notice in
    ///     any release. You should only use it directly in your code with extreme caution and knowing that
    ///     doing so can result in application failures when updating to a new Entity Framework Core release.
    /// </summary>
    public virtual InternalSkipNavigationBuilder?HasForeignKey(
        ForeignKey?foreignKey,
        ConfigurationSource configurationSource)
    {
        if (!CanSetForeignKey(foreignKey, configurationSource))
        {
            return(null);
        }

        if (foreignKey != null)
        {
            foreignKey.UpdateConfigurationSource(configurationSource);

            if (Metadata.Inverse?.JoinEntityType != null &&
                Metadata.Inverse.JoinEntityType
                != (Metadata.IsOnDependent ? foreignKey.PrincipalEntityType : foreignKey.DeclaringEntityType))
            {
                Metadata.Inverse.Builder.HasForeignKey(null, configurationSource);
            }
        }

        var oldForeignKey = Metadata.ForeignKey;

        Metadata.SetForeignKey(foreignKey, configurationSource);

        if (oldForeignKey?.IsInModel == true &&
            oldForeignKey != foreignKey &&
            oldForeignKey.ReferencingSkipNavigations?.Any() != true)
        {
            oldForeignKey.DeclaringEntityType.Builder.HasNoRelationship(oldForeignKey, ConfigurationSource.Convention);
        }

        return(this);
    }
示例#3
0
        public virtual ForeignKey?SetForeignKey([CanBeNull] ForeignKey?foreignKey, ConfigurationSource configurationSource)
        {
            EnsureReadonly(false);

            var oldForeignKey = ForeignKey;
            var isChanging    = foreignKey != ForeignKey;

            if (oldForeignKey != null)
            {
                oldForeignKey.ReferencingSkipNavigations !.Remove(this);
            }

            if (foreignKey == null)
            {
                ForeignKey = null;
                _foreignKeyConfigurationSource = null;

                return(isChanging
                    ? (ForeignKey?)DeclaringEntityType.Model.ConventionDispatcher
                       .OnSkipNavigationForeignKeyChanged(Builder, foreignKey, oldForeignKey)
                    : foreignKey);
            }

            var expectedEntityType = IsOnDependent ? foreignKey.DeclaringEntityType : foreignKey.PrincipalEntityType;

            if (expectedEntityType != DeclaringEntityType)
            {
                var message = IsOnDependent
                    ? CoreStrings.SkipNavigationForeignKeyWrongDependentType(
                    foreignKey.Properties.Format(), DeclaringEntityType.DisplayName(), Name, expectedEntityType.DisplayName())
                    : CoreStrings.SkipNavigationForeignKeyWrongPrincipalType(
                    foreignKey.Properties.Format(), DeclaringEntityType.DisplayName(), Name, expectedEntityType.DisplayName());
                throw new InvalidOperationException(message);
            }

            ProcessForeignKey(foreignKey);
            UpdateForeignKeyConfigurationSource(configurationSource);

            if (Inverse?.JoinEntityType != null &&
                Inverse.JoinEntityType != JoinEntityType)
            {
                throw new InvalidOperationException(
                          CoreStrings.SkipInverseMismatchedForeignKey(
                              foreignKey.Properties.Format(),
                              Name, JoinEntityType !.DisplayName(),
                              Inverse.Name, Inverse.JoinEntityType.DisplayName()));
            }

            return(isChanging
                ? (ForeignKey)DeclaringEntityType.Model.ConventionDispatcher
                   .OnSkipNavigationForeignKeyChanged(Builder, foreignKey, oldForeignKey)
                : foreignKey);
        }