예제 #1
0
        /// <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)
 {
 }
예제 #3
0
        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);
        }
예제 #4
0
        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));
        }
예제 #5
0
        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);
            }
        }
예제 #6
0
        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));
        }
예제 #8
0
        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));
 }
예제 #10
0
 protected OwnershipBuilder(
     InternalForeignKeyBuilder builder,
     OwnershipBuilder oldBuilder,
     bool foreignKeySet   = false,
     bool principalKeySet = false,
     bool requiredSet     = false)
     : base(builder, oldBuilder, foreignKeySet, principalKeySet, requiredSet)
 {
 }
예제 #11
0
 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)
 {
 }
예제 #13
0
 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);
            }
        }
예제 #15
0
        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));
        }
예제 #16
0
        /// <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;
예제 #18
0
 public RelationshipSnapshot(
     [NotNull] InternalForeignKeyBuilder relationship,
     [CanBeNull] EntityType.Snapshot?ownedEntityTypeSnapshot,
     [CanBeNull] List <(SkipNavigation, ConfigurationSource)>?referencingSkipNavigations)
예제 #19
0
                public ForeignKeyBuilder([NotNull] InternalForeignKeyBuilder builder)
                {
                    Check.NotNull(builder, "builder");

                    _builder = builder;
                }
예제 #20
0
        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));
        }
예제 #21
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?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);
    }
예제 #22
0
 public OwnedNavigationBuilder(IMutableForeignKey ownership)
 {
     PrincipalEntityType  = (EntityType)ownership.PrincipalEntityType;
     _dependentEntityType = (EntityType)ownership.DeclaringEntityType;
     _builder             = ((ForeignKey)ownership).Builder;
 }