public override InternalRelationshipBuilder Apply(InternalRelationshipBuilder relationshipBuilder, Navigation navigation, RequiredAttribute attribute)
        {
            Check.NotNull(relationshipBuilder, nameof(relationshipBuilder));
            Check.NotNull(navigation, nameof(navigation));
            Check.NotNull(attribute, nameof(attribute));

            if (!navigation.IsDependentToPrincipal() ||
                (navigation.DeclaringEntityType.ClrType?.GetRuntimeProperties().FirstOrDefault(pi => pi.Name == navigation.Name)?.PropertyType.TryGetSequenceType() != null))
            {
                return(relationshipBuilder);
            }
            return(relationshipBuilder.IsRequired(true, ConfigurationSource.DataAnnotation) ?? relationshipBuilder);
        }
        /// <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 InternalRelationshipBuilder Apply(InternalRelationshipBuilder relationshipBuilder)
        {
            var shouldBeRequired = true;

            foreach (var property in relationshipBuilder.Metadata.Properties)
            {
                if (property.IsNullable)
                {
                    shouldBeRequired = false;
                    relationshipBuilder.IsRequired(false, ConfigurationSource.Convention);
                    break;
                }
            }

            if (shouldBeRequired)
            {
                relationshipBuilder.IsRequired(true, ConfigurationSource.Convention);
            }

            var newRelationshipBuilder = DiscoverProperties(relationshipBuilder);

            // If new properties were used for this relationship we have to examine the other foreign keys
            // in case they can use the properties used previously.
            var fksToProcess = newRelationshipBuilder.Metadata.DeclaringEntityType.GetForeignKeysInHierarchy()
                               .Where(fk => fk != newRelationshipBuilder.Metadata)
                               .ToList();

            foreach (var fk in fksToProcess)
            {
                if (fk.Builder != null)
                {
                    DiscoverProperties(fk.Builder);
                }
            }

            return(newRelationshipBuilder);
        }
Exemple #3
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 InternalRelationshipBuilder Apply(
            InternalRelationshipBuilder relationshipBuilder,
            Navigation navigation)
        {
            Check.NotNull(relationshipBuilder, nameof(relationshipBuilder));
            Check.NotNull(navigation, nameof(navigation));

            if (!IsNonNullable(navigation) ||
                navigation.IsCollection())
            {
                return(relationshipBuilder);
            }

            if (!navigation.IsDependentToPrincipal())
            {
                var inverse = navigation.FindInverse();
                if (inverse != null)
                {
                    if (IsNonNullable(inverse))
                    {
                        Logger.NonNullableReferenceOnBothNavigations(navigation, inverse);
                        return(relationshipBuilder);
                    }
                }

                if (!navigation.ForeignKey.IsUnique ||
                    relationshipBuilder.Metadata.GetPrincipalEndConfigurationSource() != null)
                {
                    return(relationshipBuilder);
                }

                var newRelationshipBuilder = relationshipBuilder.HasEntityTypes(
                    relationshipBuilder.Metadata.DeclaringEntityType,
                    relationshipBuilder.Metadata.PrincipalEntityType,
                    ConfigurationSource.Convention);

                if (newRelationshipBuilder == null)
                {
                    return(relationshipBuilder);
                }

                Logger.NonNullableOnDependent(newRelationshipBuilder.Metadata.DependentToPrincipal);
                relationshipBuilder = newRelationshipBuilder;
            }

            return(relationshipBuilder.IsRequired(true, ConfigurationSource.Convention) ?? relationshipBuilder);
        }
        /// <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 override InternalRelationshipBuilder Apply(
            InternalRelationshipBuilder relationshipBuilder, Navigation navigation, RequiredAttribute attribute)
        {
            Check.NotNull(relationshipBuilder, nameof(relationshipBuilder));
            Check.NotNull(navigation, nameof(navigation));
            Check.NotNull(attribute, nameof(attribute));

            if (navigation.IsCollection())
            {
                return(relationshipBuilder);
            }

            if (!navigation.IsDependentToPrincipal())
            {
                var inverse = navigation.FindInverse();
                if (inverse != null)
                {
                    var attributes = GetAttributes <RequiredAttribute>(inverse.DeclaringEntityType, inverse.Name);
                    if (attributes.Any())
                    {
                        Logger.RequiredAttributeOnBothNavigations(navigation, inverse);
                        return(relationshipBuilder);
                    }
                }

                if (!navigation.ForeignKey.IsUnique ||
                    relationshipBuilder.Metadata.GetPrincipalEndConfigurationSource() != null)
                {
                    return(relationshipBuilder);
                }

                var newRelationshipBuilder = relationshipBuilder.HasEntityTypes(
                    relationshipBuilder.Metadata.DeclaringEntityType,
                    relationshipBuilder.Metadata.PrincipalEntityType,
                    ConfigurationSource.Convention);

                if (newRelationshipBuilder == null)
                {
                    return(relationshipBuilder);
                }

                Logger.RequiredAttributeOnDependent(newRelationshipBuilder.Metadata.DependentToPrincipal);
                relationshipBuilder = newRelationshipBuilder;
            }

            return(relationshipBuilder.IsRequired(true, ConfigurationSource.DataAnnotation) ?? relationshipBuilder);
        }