/// <summary> /// <para> /// Configures a relationship where this entity type has a collection that contains /// instances of the other type in the relationship. /// </para> /// <para> /// Note that calling this method with no parameters will explicitly configure this side /// of the relationship to use no navigation property, even if such a property exists on the /// entity type. If the navigation property is to be used, then it must be specified. /// </para> /// <para> /// After calling this method, you should chain a call to /// <see /// cref="CollectionNavigationBuilder{TEntity,TRelatedEntity}.WithOne(Expression{Func{TRelatedEntity,TEntity}})" /> /// to fully configure the relationship. Calling just this method without the chained call will not /// produce a valid relationship. /// </para> /// </summary> /// <typeparam name="TRelatedEntity"> The entity type that this relationship targets. </typeparam> /// <param name="navigationName"> /// The name of the collection navigation property on this entity type that represents the relationship. If /// no property is specified, the relationship will be configured without a navigation property on this /// end. /// </param> /// <returns> An object that can be used to configure the relationship. </returns> public virtual CollectionNavigationBuilder <TEntity, TRelatedEntity> HasMany <TRelatedEntity>( [CanBeNull] string navigationName) where TRelatedEntity : class { Check.NullButNotEmpty(navigationName, nameof(navigationName)); var relatedEntityType = FindRelatedEntityType(typeof(TRelatedEntity), navigationName); var skipNavigation = navigationName != null?Builder.Metadata.FindSkipNavigation(navigationName) : null; InternalForeignKeyBuilder relationship = null; if (skipNavigation == null) { relationship = Builder .HasRelationship(relatedEntityType, navigationName, ConfigurationSource.Explicit, targetIsPrincipal: false) .IsUnique(false, ConfigurationSource.Explicit); } return(new CollectionNavigationBuilder <TEntity, TRelatedEntity>( Builder.Metadata, relatedEntityType, new MemberIdentity(navigationName), relationship?.Metadata, skipNavigation)); }
public OwnedNavigationBuilder( [NotNull] EntityType principalEntityType, [NotNull] EntityType dependentEntityType, [NotNull] InternalForeignKeyBuilder builder) : base(principalEntityType, dependentEntityType, builder) { }
protected RelationshipBuilderBase( [NotNull] InternalForeignKeyBuilder builder, [NotNull] RelationshipBuilderBase oldBuilder, bool foreignKeySet = false, bool principalKeySet = false, bool requiredSet = false) { Check.NotNull(builder, nameof(builder)); Builder = builder; PrincipalEntityType = oldBuilder.PrincipalEntityType; DependentEntityType = oldBuilder.DependentEntityType; _foreignKeyProperties = foreignKeySet ? builder.Metadata.Properties : ((EntityType)oldBuilder.DependentEntityType).Builder.GetActualProperties(oldBuilder._foreignKeyProperties, null); _principalKeyProperties = principalKeySet ? builder.Metadata.PrincipalKey.Properties : ((EntityType)oldBuilder.PrincipalEntityType).Builder.GetActualProperties(oldBuilder._principalKeyProperties, null); _required = requiredSet ? builder.Metadata.IsRequired : oldBuilder._required; var foreignKey = builder.Metadata; ForeignKey.AreCompatible( (EntityType)oldBuilder.PrincipalEntityType, (EntityType)oldBuilder.DependentEntityType, foreignKey.DependentToPrincipal?.GetIdentifyingMemberInfo(), foreignKey.PrincipalToDependent?.GetIdentifyingMemberInfo(), _foreignKeyProperties, _principalKeyProperties, foreignKey.IsUnique, shouldThrow: true); }
private InternalForeignKeyBuilder WithManyBuilder(MemberIdentity collection) { var builder = Builder.HasEntityTypes( (EntityType)RelatedEntityType, (EntityType)DeclaringEntityType, ConfigurationSource.Explicit); var collectionName = collection.Name; if (builder.Metadata.IsUnique && builder.Metadata.PrincipalToDependent != null && builder.Metadata.GetPrincipalToDependentConfigurationSource() == ConfigurationSource.Explicit && collectionName != null) { InternalForeignKeyBuilder.ThrowForConflictingNavigation(builder.Metadata, collectionName, false); } builder = builder.IsUnique(false, ConfigurationSource.Explicit); var foreignKey = builder.Metadata; if (collectionName != null && foreignKey.PrincipalToDependent != null && foreignKey.GetPrincipalToDependentConfigurationSource() == ConfigurationSource.Explicit && foreignKey.PrincipalToDependent.Name != collectionName) { InternalForeignKeyBuilder.ThrowForConflictingNavigation(foreignKey, collectionName, false); } return(collection.MemberInfo == null || ReferenceMember == null ? builder.HasNavigations( ReferenceName, collection.Name, (EntityType)RelatedEntityType, (EntityType)DeclaringEntityType, ConfigurationSource.Explicit) : builder.HasNavigations( ReferenceMember, collection.MemberInfo, (EntityType)RelatedEntityType, (EntityType)DeclaringEntityType, ConfigurationSource.Explicit)); }
protected virtual IMutableSkipNavigation WithLeftManyNavigation([NotNull] string inverseName) { Check.NotEmpty(inverseName, nameof(inverseName)); if (SkipNavigation != null) { return(SkipNavigation); } var foreignKey = Builder.Metadata; var navigationMember = foreignKey.PrincipalToDependent.CreateMemberIdentity(); if (foreignKey.GetDependentToPrincipalConfigurationSource() == ConfigurationSource.Explicit) { InternalForeignKeyBuilder.ThrowForConflictingNavigation( foreignKey, DeclaringEntityType, RelatedEntityType, navigationMember.Name, inverseName); } using (foreignKey.DeclaringEntityType.Model.ConventionDispatcher.DelayConventions()) { foreignKey.DeclaringEntityType.RemoveForeignKey(foreignKey); Builder = null; return(((EntityType)DeclaringEntityType).Builder.HasSkipNavigation( navigationMember, (EntityType)RelatedEntityType, ConfigurationSource.Explicit).Metadata); } }
private IMutableSkipNavigation WithRightManyNavigation(MemberIdentity navigationMember, [NotNull] string inverseName) { Check.DebugAssert(Builder == null, "Expected no associated foreign key at this point"); var navigationName = navigationMember.Name; var conflictingNavigation = RelatedEntityType.FindNavigation(navigationName) as IConventionNavigation; var foreignKey = (ForeignKey)conflictingNavigation?.ForeignKey; if (conflictingNavigation?.GetConfigurationSource() == ConfigurationSource.Explicit) { InternalForeignKeyBuilder.ThrowForConflictingNavigation( foreignKey, DeclaringEntityType, RelatedEntityType, inverseName, navigationName); } using (((EntityType)RelatedEntityType).Model.ConventionDispatcher.DelayConventions()) { if (conflictingNavigation != null) { foreignKey.DeclaringEntityType.RemoveForeignKey(foreignKey); } else { var skipNavigation = RelatedEntityType.FindSkipNavigation(navigationMember.Name); if (skipNavigation != null) { return(skipNavigation); } } return(((EntityType)RelatedEntityType).Builder.HasSkipNavigation( navigationMember, (EntityType)DeclaringEntityType, ConfigurationSource.Explicit).Metadata); } }
private InternalForeignKeyBuilder WithOneBuilder(MemberIdentity reference) { if (SkipNavigation != null) { // Note: we delayed setting the ConfigurationSource of SkipNavigation in HasMany() // so we can test it here and override if the skip navigation was originally found // by convention. if (((IConventionSkipNavigation)SkipNavigation).GetConfigurationSource() == ConfigurationSource.Explicit) { throw new InvalidOperationException( CoreStrings.ConflictingRelationshipNavigation( SkipNavigation.DeclaringEntityType.DisplayName() + "." + SkipNavigation.Name, RelatedEntityType.DisplayName() + (reference.Name == null ? "" : "." + reference.Name), SkipNavigation.DeclaringEntityType.DisplayName() + "." + SkipNavigation.Name, SkipNavigation.TargetEntityType.DisplayName() + (SkipNavigation.Inverse == null ? "" : "." + SkipNavigation.Inverse.Name))); } var navigationName = SkipNavigation.Name; var declaringEntityType = (EntityType)DeclaringEntityType; declaringEntityType.Model.Builder .RemoveAssociationEntityIfCreatedImplicitly( (EntityType)SkipNavigation.AssociationEntityType, removeSkipNavigations: true, ConfigurationSource.Explicit); Builder = declaringEntityType.Builder .HasRelationship( (EntityType)RelatedEntityType, navigationName, ConfigurationSource.Explicit, targetIsPrincipal: false); SkipNavigation = null; } var foreignKey = Builder.Metadata; var referenceName = reference.Name; if (referenceName != null && foreignKey.DependentToPrincipal != null && foreignKey.GetDependentToPrincipalConfigurationSource() == ConfigurationSource.Explicit && foreignKey.DependentToPrincipal.Name != referenceName) { InternalForeignKeyBuilder.ThrowForConflictingNavigation(foreignKey, referenceName, newToPrincipal: true); } return(reference.MemberInfo == null || CollectionMember == null ? Builder.HasNavigations( reference.Name, CollectionName, (EntityType)DeclaringEntityType, (EntityType)RelatedEntityType, ConfigurationSource.Explicit) : Builder.HasNavigations( reference.MemberInfo, CollectionMember, (EntityType)DeclaringEntityType, (EntityType)RelatedEntityType, ConfigurationSource.Explicit)); }
private Navigation RunConvention(InternalForeignKeyBuilder relationshipBuilder, Navigation navigation) { var context = new ConventionContext <IConventionNavigationBuilder>( relationshipBuilder.Metadata.DeclaringEntityType.Model.ConventionDispatcher); CreateNotNullNavigationConvention().ProcessNavigationAdded(navigation.Builder, context); return(context.ShouldStopProcessing() ? (Navigation)context.Result?.Metadata : navigation); }
private static void RunConvention(InternalForeignKeyBuilder foreignKeyBuilder) { new ValueGenerationConvention(CreateDependencies()) .ProcessForeignKeyAdded( foreignKeyBuilder, new ConventionContext <IConventionForeignKeyBuilder>( foreignKeyBuilder.Metadata.DeclaringEntityType.Model.ConventionDispatcher)); }
protected OwnershipBuilder( InternalForeignKeyBuilder builder, OwnershipBuilder oldBuilder, bool foreignKeySet = false, bool principalKeySet = false, bool requiredSet = false) : base(builder, oldBuilder, foreignKeySet, principalKeySet, requiredSet) { }
public OwnedNavigationBuilder( [NotNull] EntityType principalEntityType, [NotNull] EntityType dependentEntityType, [NotNull] InternalForeignKeyBuilder builder) { PrincipalEntityType = principalEntityType; DependentEntityType = dependentEntityType; _builder = builder; }
protected ReferenceCollectionBuilder( [NotNull] InternalForeignKeyBuilder builder, [CanBeNull] ReferenceCollectionBuilder oldBuilder, bool foreignKeySet = false, bool principalKeySet = false, bool requiredSet = false) : base(builder, oldBuilder, foreignKeySet, principalKeySet, requiredSet) { }
protected ReferenceReferenceBuilder( InternalForeignKeyBuilder builder, ReferenceReferenceBuilder oldBuilder, bool inverted = false, bool foreignKeySet = false, bool principalKeySet = false, bool requiredSet = false) : base(builder, oldBuilder, inverted, foreignKeySet, principalKeySet, requiredSet) { }
protected InvertibleRelationshipBuilderBase( [NotNull] InternalForeignKeyBuilder builder, [CanBeNull] InvertibleRelationshipBuilderBase oldBuilder, bool inverted = false, bool foreignKeySet = false, bool principalKeySet = false, bool requiredSet = false) { Builder = builder; if (oldBuilder != null) { if (inverted) { if (oldBuilder._foreignKeyProperties != null || oldBuilder._principalKeyProperties != null) { throw new InvalidOperationException(CoreStrings.RelationshipCannotBeInverted); } } DeclaringEntityType = oldBuilder.DeclaringEntityType; RelatedEntityType = oldBuilder.RelatedEntityType; _foreignKeyProperties = foreignKeySet ? builder.Metadata.Properties : oldBuilder._foreignKeyProperties; _principalKeyProperties = principalKeySet ? builder.Metadata.PrincipalKey.Properties : oldBuilder._principalKeyProperties; _required = requiredSet ? builder.Metadata.IsRequired : oldBuilder._required; var foreignKey = builder.Metadata; ForeignKey.AreCompatible( foreignKey.PrincipalEntityType, foreignKey.DeclaringEntityType, foreignKey.DependentToPrincipal?.GetIdentifyingMemberInfo(), foreignKey.PrincipalToDependent?.GetIdentifyingMemberInfo(), _foreignKeyProperties, _principalKeyProperties, foreignKey.IsUnique, shouldThrow: true); } }
private InternalForeignKeyBuilder WithOneBuilder(MemberIdentity reference) { if (SkipNavigation != null) { throw new InvalidOperationException( CoreStrings.ConflictingRelationshipNavigation( SkipNavigation.DeclaringEntityType.DisplayName() + "." + SkipNavigation.Name, RelatedEntityType.DisplayName() + (reference.Name == null ? "" : "." + reference.Name), SkipNavigation.DeclaringEntityType.DisplayName() + "." + SkipNavigation.Name, SkipNavigation.TargetEntityType.DisplayName() + (SkipNavigation.Inverse == null ? "" : "." + SkipNavigation.Inverse.Name))); } var foreignKey = Builder.Metadata; var referenceName = reference.Name; if (referenceName != null && foreignKey.DependentToPrincipal != null && foreignKey.GetDependentToPrincipalConfigurationSource() == ConfigurationSource.Explicit && foreignKey.DependentToPrincipal.Name != referenceName) { InternalForeignKeyBuilder.ThrowForConflictingNavigation(foreignKey, referenceName, newToPrincipal: true); } return(reference.MemberInfo == null || CollectionMember == null ? Builder.HasNavigations( reference.Name, CollectionName, (EntityType)DeclaringEntityType, (EntityType)RelatedEntityType, ConfigurationSource.Explicit) : Builder.HasNavigations( reference.MemberInfo, CollectionMember, (EntityType)DeclaringEntityType, (EntityType)RelatedEntityType, ConfigurationSource.Explicit)); }
/// <summary> /// <para> /// Configures a relationship where this entity type has a collection that contains /// instances of the other type in the relationship. /// </para> /// <para> /// Note that calling this method with no parameters will explicitly configure this side /// of the relationship to use no navigation property, even if such a property exists on the /// entity type. If the navigation property is to be used, then it must be specified. /// </para> /// <para> /// After calling this method, you should chain a call to /// <see /// cref="CollectionNavigationBuilder{TEntity,TRelatedEntity}.WithOne(Expression{Func{TRelatedEntity,TEntity}})" /> /// to fully configure the relationship. Calling just this method without the chained call will not /// produce a valid relationship. /// </para> /// </summary> /// <typeparam name="TRelatedEntity"> The entity type that this relationship targets. </typeparam> /// <param name="navigationExpression"> /// A lambda expression representing the collection navigation property on this entity type that represents /// the relationship (<c>blog => blog.Posts</c>). If no property is specified, the relationship will be /// configured without a navigation property on this end. /// </param> /// <returns> An object that can be used to configure the relationship. </returns> public virtual CollectionNavigationBuilder <TEntity, TRelatedEntity> HasMany <TRelatedEntity>( [CanBeNull] Expression <Func <TEntity, IEnumerable <TRelatedEntity> > > navigationExpression = null) where TRelatedEntity : class { var navigationMember = navigationExpression?.GetPropertyAccess(); var relatedEntityType = FindRelatedEntityType(typeof(TRelatedEntity), navigationMember?.GetSimpleMemberName()); var skipNavigation = navigationMember != null?Builder.Metadata.FindSkipNavigation(navigationMember) : null; InternalForeignKeyBuilder relationship = null; if (skipNavigation == null) { relationship = Builder .HasRelationship(relatedEntityType, navigationMember, ConfigurationSource.Explicit, targetIsPrincipal: false) .IsUnique(false, ConfigurationSource.Explicit); } return(new CollectionNavigationBuilder <TEntity, TRelatedEntity>( Builder.Metadata, relatedEntityType, new MemberIdentity(navigationMember), relationship?.Metadata, skipNavigation)); }
public static InternalForeignKeyBuilder?Run( [NotNull] this IConventionBatch batch, [NotNull] InternalForeignKeyBuilder relationshipBuilder) => (InternalForeignKeyBuilder?)batch.Run(relationshipBuilder.Metadata)?.Builder;
public RelationshipSnapshot( [NotNull] InternalForeignKeyBuilder relationship, [CanBeNull] EntityType.Snapshot?ownedEntityTypeSnapshot, [CanBeNull] List <(SkipNavigation, ConfigurationSource)>?referencingSkipNavigations)
public ForeignKeyBuilder([NotNull] InternalForeignKeyBuilder builder) { Check.NotNull(builder, "builder"); _builder = builder; }
private InternalForeignKeyBuilder WithOneBuilder(MemberIdentity reference) { var referenceName = reference.Name; if (!Builder.Metadata.IsUnique && Builder.Metadata.PrincipalToDependent != null && Builder.Metadata.GetPrincipalToDependentConfigurationSource() == ConfigurationSource.Explicit && referenceName != null) { InternalForeignKeyBuilder.ThrowForConflictingNavigation(Builder.Metadata, referenceName, false); } using var batch = Builder.Metadata.DeclaringEntityType.Model.ConventionDispatcher.DelayConventions(); var builder = Builder.IsUnique(true, ConfigurationSource.Explicit); var foreignKey = builder.Metadata; if (foreignKey.IsSelfReferencing() && referenceName != null && ReferenceName == referenceName) { throw new InvalidOperationException( CoreStrings.ConflictingPropertyOrNavigation( referenceName, RelatedEntityType.DisplayName(), RelatedEntityType.DisplayName())); } var pointsToPrincipal = !foreignKey.IsSelfReferencing() && (!foreignKey.DeclaringEntityType.IsAssignableFrom(DeclaringEntityType) || !foreignKey.PrincipalEntityType.IsAssignableFrom(RelatedEntityType) || (foreignKey.DeclaringEntityType.IsAssignableFrom(RelatedEntityType) && foreignKey.PrincipalEntityType.IsAssignableFrom(DeclaringEntityType) && foreignKey.PrincipalToDependent != null && foreignKey.PrincipalToDependent.Name == ReferenceName)); if (referenceName != null && ((pointsToPrincipal && foreignKey.DependentToPrincipal != null && foreignKey.GetDependentToPrincipalConfigurationSource() == ConfigurationSource.Explicit && foreignKey.DependentToPrincipal.Name != referenceName) || (!pointsToPrincipal && foreignKey.PrincipalToDependent != null && foreignKey.GetPrincipalToDependentConfigurationSource() == ConfigurationSource.Explicit && foreignKey.PrincipalToDependent.Name != referenceName))) { InternalForeignKeyBuilder.ThrowForConflictingNavigation(foreignKey, referenceName, pointsToPrincipal); } var referenceProperty = reference.MemberInfo; if (pointsToPrincipal) { builder = referenceProperty == null || ReferenceMember == null ? builder.HasNavigations( referenceName, ReferenceName, (EntityType)DeclaringEntityType, (EntityType)RelatedEntityType, ConfigurationSource.Explicit) : builder.HasNavigations( referenceProperty, ReferenceMember, (EntityType)DeclaringEntityType, (EntityType)RelatedEntityType, ConfigurationSource.Explicit); } else { builder = referenceProperty == null || ReferenceMember == null ? builder.HasNavigations( ReferenceName, referenceName, (EntityType)RelatedEntityType, (EntityType)DeclaringEntityType, ConfigurationSource.Explicit) : builder.HasNavigations( ReferenceMember, referenceProperty, (EntityType)RelatedEntityType, (EntityType)DeclaringEntityType, ConfigurationSource.Explicit); } return(batch.Run(builder)); }
/// <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?Attach( InternalEntityTypeBuilder?entityTypeBuilder = null, EntityType?targetEntityType = null, InternalSkipNavigationBuilder?inverseBuilder = null) { if (entityTypeBuilder is null) { if (Metadata.DeclaringEntityType.IsInModel) { entityTypeBuilder = Metadata.DeclaringEntityType.Builder; } else if (Metadata.DeclaringEntityType.Model.FindEntityType(Metadata.DeclaringEntityType.Name) is EntityType entityType) { entityTypeBuilder = entityType.Builder; } else { return(null); } } targetEntityType ??= Metadata.TargetEntityType; if (!targetEntityType.IsInModel) { targetEntityType = Metadata.DeclaringEntityType.Model.FindEntityType(targetEntityType.Name); if (targetEntityType == null) { return(null); } } var newSkipNavigationBuilder = entityTypeBuilder.HasSkipNavigation( Metadata.CreateMemberIdentity(), targetEntityType, Metadata.GetConfigurationSource(), Metadata.IsCollection, Metadata.IsOnDependent); if (newSkipNavigationBuilder == null) { return(null); } newSkipNavigationBuilder.MergeAnnotationsFrom(Metadata); var foreignKeyConfigurationSource = Metadata.GetForeignKeyConfigurationSource(); if (foreignKeyConfigurationSource.HasValue) { var foreignKey = Metadata.ForeignKey !; if (!foreignKey.IsInModel) { foreignKey = InternalForeignKeyBuilder.FindCurrentForeignKeyBuilder( foreignKey.PrincipalEntityType, foreignKey.DeclaringEntityType, foreignKey.DependentToPrincipal?.CreateMemberIdentity(), foreignKey.PrincipalToDependent?.CreateMemberIdentity(), dependentProperties: foreignKey.Properties, principalProperties: foreignKey.PrincipalKey.Properties)?.Metadata; } if (foreignKey != null) { newSkipNavigationBuilder.HasForeignKey(foreignKey, foreignKeyConfigurationSource.Value); } } var inverseConfigurationSource = Metadata.GetInverseConfigurationSource(); if (inverseConfigurationSource.HasValue) { var inverse = Metadata.Inverse !; if (!inverse.IsInModel) { inverse = inverse.DeclaringEntityType.FindSkipNavigation(inverse.Name); } if (inverseBuilder != null) { inverse = inverseBuilder.Attach(targetEntityType.Builder, entityTypeBuilder.Metadata)?.Metadata ?? inverse; } if (inverse != null) { newSkipNavigationBuilder.HasInverse(inverse, inverseConfigurationSource.Value); } } var propertyAccessModeConfigurationSource = Metadata.GetPropertyAccessModeConfigurationSource(); if (propertyAccessModeConfigurationSource.HasValue) { newSkipNavigationBuilder.UsePropertyAccessMode( Metadata.GetPropertyAccessMode(), propertyAccessModeConfigurationSource.Value); } var oldFieldInfoConfigurationSource = Metadata.GetFieldInfoConfigurationSource(); if (oldFieldInfoConfigurationSource.HasValue && newSkipNavigationBuilder.CanSetField(Metadata.FieldInfo, oldFieldInfoConfigurationSource)) { newSkipNavigationBuilder.HasField(Metadata.FieldInfo, oldFieldInfoConfigurationSource.Value); } return(newSkipNavigationBuilder); }
public OwnedNavigationBuilder(IMutableForeignKey ownership) { PrincipalEntityType = (EntityType)ownership.PrincipalEntityType; _dependentEntityType = (EntityType)ownership.DeclaringEntityType; _builder = ((ForeignKey)ownership).Builder; }