示例#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 SkipNavigation(
            [NotNull] string name,
            [CanBeNull] PropertyInfo propertyInfo,
            [CanBeNull] FieldInfo fieldInfo,
            [NotNull] EntityType declaringEntityType,
            [NotNull] EntityType targetEntityType,
            bool collection,
            bool onDependent,
            ConfigurationSource configurationSource)
            : base(name, propertyInfo, fieldInfo, configurationSource)
        {
            Check.NotNull(declaringEntityType, nameof(declaringEntityType));
            Check.NotNull(targetEntityType, nameof(targetEntityType));

            DeclaringEntityType = declaringEntityType;
            TargetEntityType    = targetEntityType;
            IsCollection        = collection;
            IsOnDependent       = onDependent;
            Builder             = new InternalSkipNavigationBuilder(this, targetEntityType.Model.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 SkipNavigation(
            [NotNull] string name,
            [CanBeNull] PropertyInfo propertyInfo,
            [CanBeNull] FieldInfo fieldInfo,
            [NotNull] EntityType targetEntityType,
            [NotNull] ForeignKey foreignKey,
            bool collection,
            bool onPrincipal,
            ConfigurationSource configurationSource)
            : base(name, propertyInfo, fieldInfo)
        {
            Check.NotNull(foreignKey, nameof(foreignKey));

            TargetEntityType     = targetEntityType;
            ForeignKey           = foreignKey;
            IsCollection         = collection;
            IsOnPrincipal        = onPrincipal;
            _configurationSource = configurationSource;
            Builder = new InternalSkipNavigationBuilder(this, targetEntityType.Model.Builder);
        }
示例#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 SkipNavigation(
            [NotNull] string name,
            [CanBeNull] PropertyInfo propertyInfo,
            [CanBeNull] FieldInfo fieldInfo,
            [NotNull] EntityType declaringEntityType,
            [NotNull] EntityType targetEntityType,
            [CanBeNull] ForeignKey foreignKey,
            bool collection,
            bool onPrincipal,
            ConfigurationSource configurationSource)
            : base(name, propertyInfo, fieldInfo)
        {
            Check.NotNull(declaringEntityType, nameof(declaringEntityType));
            Check.NotNull(targetEntityType, nameof(targetEntityType));

            DeclaringEntityType  = declaringEntityType;
            TargetEntityType     = targetEntityType;
            IsCollection         = collection;
            IsOnPrincipal        = onPrincipal;
            _configurationSource = configurationSource;
            Builder = new InternalSkipNavigationBuilder(this, targetEntityType.Model.Builder);

            if (foreignKey != null)
            {
                var expectedEntityType = IsOnPrincipal ? foreignKey.PrincipalEntityType : foreignKey.DeclaringEntityType;
                if (expectedEntityType != DeclaringEntityType)
                {
                    var message = IsOnPrincipal
                        ? CoreStrings.SkipNavigationWrongPrincipalType(
                        Name, DeclaringEntityType.DisplayName(), expectedEntityType.DisplayName(), foreignKey.Properties.Format())
                        : CoreStrings.SkipNavigationWrongDependentType(
                        Name, DeclaringEntityType.DisplayName(), expectedEntityType.DisplayName(), foreignKey.Properties.Format());
                    throw new InvalidOperationException(message);
                }

                ProcessForeignKey(foreignKey);
                UpdateForeignKeyConfigurationSource(configurationSource);
            }
        }
        /// <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(
            [CanBeNull] InternalEntityTypeBuilder entityTypeBuilder = null,
            [CanBeNull] EntityType targetEntityType = null,
            [CanBeNull] InternalSkipNavigationBuilder inverseBuilder = null)
        {
            entityTypeBuilder ??= Metadata.DeclaringEntityType.Builder;
            if (entityTypeBuilder == null)
            {
                entityTypeBuilder = Metadata.DeclaringEntityType.Model.FindEntityType(Metadata.DeclaringEntityType.Name)?.Builder;
                if (entityTypeBuilder == null)
                {
                    return(null);
                }
            }

            targetEntityType ??= Metadata.TargetEntityType;
            if (targetEntityType.Builder == null)
            {
                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.Builder == null)
                {
                    foreignKey = InternalRelationshipBuilder.FindCurrentRelationshipBuilder(
                        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.Builder == null)
                {
                    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(
                    ((ISkipNavigation)Metadata).GetPropertyAccessMode(), propertyAccessModeConfigurationSource.Value);
            }

            var oldFieldInfoConfigurationSource = Metadata.GetFieldInfoConfigurationSource();

            if (oldFieldInfoConfigurationSource.HasValue &&
                newSkipNavigationBuilder.CanSetField(Metadata.FieldInfo, oldFieldInfoConfigurationSource))
            {
                newSkipNavigationBuilder.HasField(Metadata.FieldInfo, oldFieldInfoConfigurationSource.Value);
            }

            return(newSkipNavigationBuilder);
        }