/// <summary> /// Called after a navigation is added to the entity type. /// </summary> /// <param name="relationshipBuilder"> The builder for the foreign key. </param> /// <param name="navigation"> The navigation. </param> /// <param name="context"> Additional information associated with convention execution. </param> public virtual void ProcessNavigationAdded( IConventionRelationshipBuilder relationshipBuilder, IConventionNavigation navigation, IConventionContext <IConventionNavigation> context) { Check.NotNull(relationshipBuilder, nameof(relationshipBuilder)); Check.NotNull(navigation, nameof(navigation)); var modelBuilder = relationshipBuilder.ModelBuilder; if (!IsNonNullable(modelBuilder, navigation) || navigation.IsCollection()) { return; } if (!navigation.IsDependentToPrincipal()) { var inverse = navigation.FindInverse(); if (inverse != null) { if (IsNonNullable(modelBuilder, inverse)) { Dependencies.Logger.NonNullableReferenceOnBothNavigations(navigation, inverse); return; } } if (!navigation.ForeignKey.IsUnique || relationshipBuilder.Metadata.GetPrincipalEndConfigurationSource() != null) { Dependencies.Logger.NonNullableReferenceOnDependent(navigation.ForeignKey.PrincipalToDependent); return; } var newRelationshipBuilder = relationshipBuilder.HasEntityTypes( relationshipBuilder.Metadata.DeclaringEntityType, relationshipBuilder.Metadata.PrincipalEntityType); if (newRelationshipBuilder == null) { return; } Dependencies.Logger.NonNullableInverted(newRelationshipBuilder.Metadata.DependentToPrincipal); relationshipBuilder = newRelationshipBuilder; } relationshipBuilder.IsRequired(true); context.StopProcessingIfChanged(relationshipBuilder.Metadata.DependentToPrincipal); }
/// <summary> /// Called after a navigation property that has an attribute is added to an entity type. /// </summary> /// <param name="relationshipBuilder"> The builder for the relationship. </param> /// <param name="navigation"> The navigation. </param> /// <param name="attribute"> The attribute. </param> /// <param name="context"> Additional information associated with convention execution. </param> public override void ProcessNavigationAdded( IConventionRelationshipBuilder relationshipBuilder, IConventionNavigation navigation, RequiredAttribute attribute, IConventionContext <IConventionNavigation> context) { Check.NotNull(relationshipBuilder, nameof(relationshipBuilder)); Check.NotNull(navigation, nameof(navigation)); Check.NotNull(attribute, nameof(attribute)); if (navigation.IsCollection()) { Dependencies.Logger.RequiredAttributeOnCollection(navigation.ForeignKey.DependentToPrincipal); return; } if (!navigation.IsDependentToPrincipal()) { var inverse = navigation.FindInverse(); if (inverse != null) { var attributes = GetAttributes <RequiredAttribute>(inverse.DeclaringEntityType, inverse); if (attributes.Any()) { Dependencies.Logger.RequiredAttributeOnBothNavigations(navigation, inverse); return; } } if (relationshipBuilder.Metadata.GetPrincipalEndConfigurationSource() != null) { Dependencies.Logger.RequiredAttributeOnDependent(navigation.ForeignKey.PrincipalToDependent); return; } var newRelationshipBuilder = relationshipBuilder.HasEntityTypes( relationshipBuilder.Metadata.DeclaringEntityType, relationshipBuilder.Metadata.PrincipalEntityType); if (newRelationshipBuilder == null) { return; } Dependencies.Logger.RequiredAttributeInverted(newRelationshipBuilder.Metadata.DependentToPrincipal); relationshipBuilder = newRelationshipBuilder; } relationshipBuilder.IsRequired(true, fromDataAnnotation: true); context.StopProcessingIfChanged(relationshipBuilder.Metadata.DependentToPrincipal); }