Example #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 virtual IConventionForeignKey OnSkipNavigationForeignKeyChanged(
     [NotNull] IConventionSkipNavigationBuilder navigationBuilder,
     [NotNull] IConventionForeignKey foreignKey,
     [NotNull] IConventionForeignKey oldForeignKey)
 => _scope.OnSkipNavigationForeignKeyChanged(navigationBuilder, foreignKey, oldForeignKey);
Example #2
0
 /// <inheritdoc />
 IMetadataReference <IConventionForeignKey> IConventionBatch.Track(IConventionForeignKey foreignKey)
 => _dispatcher.Tracker.Track(foreignKey);
 /// <summary>
 ///     Gets the <see cref="ConfigurationSource" /> for the constraint name.
 /// </summary>
 /// <param name="foreignKey"> The foreign key. </param>
 /// <returns> The <see cref="ConfigurationSource" /> for the constraint name. </returns>
 public static ConfigurationSource?GetConstraintNameConfigurationSource([NotNull] this IConventionForeignKey foreignKey)
 => foreignKey.FindAnnotation(RelationalAnnotationNames.Name)
 ?.GetConfigurationSource();
Example #4
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 IConventionForeignKey OnForeignKeyRemoved(
     [NotNull] IConventionEntityTypeBuilder entityTypeBuilder, [NotNull] IConventionForeignKey foreignKey)
 => _scope.OnForeignKeyRemoved(entityTypeBuilder, foreignKey);
 /// <summary>
 ///     Sets the foreign key constraint name.
 /// </summary>
 /// <param name="foreignKey"> The foreign key. </param>
 /// <param name="value"> The value to set. </param>
 /// <param name="fromDataAnnotation"> Indicates whether the configuration was specified using a data annotation. </param>
 public static void SetConstraintName(
     [NotNull] this IConventionForeignKey foreignKey, [CanBeNull] string value, bool fromDataAnnotation = false)
 => foreignKey.SetOrRemoveAnnotation(
     RelationalAnnotationNames.Name,
     Check.NullButNotEmpty(value, nameof(value)),
     fromDataAnnotation);
 private static string GetPropertyBaseName(IConventionForeignKey foreignKey)
 => foreignKey.DependentToPrincipal?.Name ?? foreignKey.PrincipalEntityType.ShortName();
        private bool TryFindMatchingProperties(
            IConventionForeignKey foreignKey,
            string baseName,
            bool onDependent,
            bool matchPk,
            out IReadOnlyList <IConventionProperty> match)
        {
            match = null;
            var dependentEntityType = onDependent
                ? foreignKey.DeclaringEntityType
                : foreignKey.PrincipalEntityType;
            var principalEntityType = onDependent
                ? foreignKey.PrincipalEntityType
                : foreignKey.DeclaringEntityType;
            var propertiesToReference = onDependent
                ? foreignKey.PrincipalKey.Properties
                : foreignKey.DeclaringEntityType.FindPrimaryKey()?.Properties;

            if (propertiesToReference == null)
            {
                return(false);
            }

            var foreignKeyProperties = new IConventionProperty[propertiesToReference.Count];
            var matchFound           = true;

            for (var i = 0; i < propertiesToReference.Count; i++)
            {
                var referencedProperty = propertiesToReference[i];
                var property           = TryGetProperty(
                    dependentEntityType,
                    baseName, referencedProperty.Name);

                if (property == null)
                {
                    matchFound = false;
                    continue;
                }

                foreignKeyProperties[i] = property;
            }

            if (!matchFound &&
                propertiesToReference.Count == 1 &&
                baseName.Length > 0)
            {
                var property = TryGetProperty(
                    dependentEntityType,
                    baseName, "Id");

                if (property != null)
                {
                    foreignKeyProperties[0] = property;
                    matchFound = true;
                }
            }

            if (!matchFound)
            {
                return(false);
            }

            if (!ForeignKey.AreCompatible(
                    propertiesToReference,
                    foreignKeyProperties,
                    principalEntityType,
                    dependentEntityType,
                    shouldThrow: false))
            {
                if (propertiesToReference.All(
                        p => !p.IsShadowProperty() ||
                        p.GetConfigurationSource().Overrides(ConfigurationSource.DataAnnotation)))
                {
                    Dependencies.Logger.IncompatibleMatchingForeignKeyProperties(foreignKeyProperties, propertiesToReference);
                }

                // Stop searching if match found, but is incompatible
                return(true);
            }

            foreach (var key in dependentEntityType.GetKeys())
            {
                var isKeyContainedInForeignKey = true;
                // ReSharper disable once LoopCanBeConvertedToQuery
                // ReSharper disable once ForCanBeConvertedToForeach
                for (var i = 0; i < key.Properties.Count; i++)
                {
                    if (!foreignKeyProperties.Contains(key.Properties[i]))
                    {
                        isKeyContainedInForeignKey = false;
                        break;
                    }
                }

                if (isKeyContainedInForeignKey &&
                    (!foreignKey.IsUnique ||
                     (key.IsPrimaryKey() &&
                      !matchPk)))
                {
                    // Stop searching if match found, but is incompatible
                    return(true);
                }
            }

            match = foreignKeyProperties;
            return(true);
        }
Example #8
0
 private IConventionRelationshipBuilder ReuniquifyTemporaryProperties(IConventionForeignKey foreignKey, bool force)
 => ((ForeignKey)foreignKey).Builder.ReuniquifyTemporaryProperties(force);
 /// <summary>
 ///     Returns the delete behavior to set for the given foreign key.
 /// </summary>
 /// <param name="foreignKey">The foreign key.</param>
 protected virtual DeleteBehavior GetTargetDeleteBehavior(IConventionForeignKey foreignKey)
 => foreignKey.IsRequired ? DeleteBehavior.Cascade : DeleteBehavior.ClientSetNull;