/// <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 static bool AreCompatibleForSqlServer(
            [NotNull] this IKey key,
            [NotNull] IKey duplicateKey,
            StoreObjectIdentifier storeObject,
            bool shouldThrow)
        {
            if (key.IsClustered(storeObject)
                != duplicateKey.IsClustered(storeObject))
            {
                if (shouldThrow)
                {
                    throw new InvalidOperationException(
                              SqlServerStrings.DuplicateKeyMismatchedClustering(
                                  key.Properties.Format(),
                                  key.DeclaringEntityType.DisplayName(),
                                  duplicateKey.Properties.Format(),
                                  duplicateKey.DeclaringEntityType.DisplayName(),
                                  storeObject.DisplayName(),
                                  key.GetName(storeObject)));
                }

                return(false);
            }

            return(true);
        }
Example #2
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>
        protected override void ValidateCompatible(
            IProperty property,
            IProperty duplicateProperty,
            string columnName,
            StoreObjectIdentifier storeObject,
            IDiagnosticsLogger <DbLoggerCategory.Model.Validation> logger)
        {
            base.ValidateCompatible(property, duplicateProperty, columnName, storeObject, logger);

            var propertySrid          = property.GetSrid(storeObject);
            var duplicatePropertySrid = duplicateProperty.GetSrid(storeObject);

            if (propertySrid != duplicatePropertySrid)
            {
                throw new InvalidOperationException(
                          SqliteStrings.DuplicateColumnNameSridMismatch(
                              duplicateProperty.DeclaringEntityType.DisplayName(),
                              duplicateProperty.Name,
                              property.DeclaringEntityType.DisplayName(),
                              property.Name,
                              columnName,
                              storeObject.DisplayName()));
            }
        }
        /// <inheritdoc />
        protected override void ValidateCompatible(
            IProperty property,
            IProperty duplicateProperty,
            string columnName,
            StoreObjectIdentifier storeObject,
            IDiagnosticsLogger <DbLoggerCategory.Model.Validation> logger)
        {
            base.ValidateCompatible(property, duplicateProperty, columnName, storeObject, logger);

            var propertyStrategy          = property.GetValueGenerationStrategy(storeObject);
            var duplicatePropertyStrategy = duplicateProperty.GetValueGenerationStrategy(storeObject);

            if (propertyStrategy != duplicatePropertyStrategy)
            {
                throw new InvalidOperationException(
                          SqlServerStrings.DuplicateColumnNameValueGenerationStrategyMismatch(
                              duplicateProperty.DeclaringEntityType.DisplayName(),
                              duplicateProperty.Name,
                              property.DeclaringEntityType.DisplayName(),
                              property.Name,
                              columnName,
                              storeObject.DisplayName()));
            }

            switch (propertyStrategy)
            {
            case SqlServerValueGenerationStrategy.IdentityColumn:
                var increment          = property.GetIdentityIncrement();
                var duplicateIncrement = duplicateProperty.GetIdentityIncrement();
                if (increment != duplicateIncrement)
                {
                    throw new InvalidOperationException(
                              SqlServerStrings.DuplicateColumnIdentityIncrementMismatch(
                                  duplicateProperty.DeclaringEntityType.DisplayName(),
                                  duplicateProperty.Name,
                                  property.DeclaringEntityType.DisplayName(),
                                  property.Name,
                                  columnName,
                                  storeObject.DisplayName()));
                }

                var seed          = property.GetIdentitySeed();
                var duplicateSeed = duplicateProperty.GetIdentitySeed();
                if (seed != duplicateSeed)
                {
                    throw new InvalidOperationException(
                              SqlServerStrings.DuplicateColumnIdentitySeedMismatch(
                                  duplicateProperty.DeclaringEntityType.DisplayName(),
                                  duplicateProperty.Name,
                                  property.DeclaringEntityType.DisplayName(),
                                  property.Name,
                                  columnName,
                                  storeObject.DisplayName()));
                }

                break;

            case SqlServerValueGenerationStrategy.SequenceHiLo:
                if (property.GetHiLoSequenceName() != duplicateProperty.GetHiLoSequenceName() ||
                    property.GetHiLoSequenceSchema() != duplicateProperty.GetHiLoSequenceSchema())
                {
                    throw new InvalidOperationException(
                              SqlServerStrings.DuplicateColumnSequenceMismatch(
                                  duplicateProperty.DeclaringEntityType.DisplayName(),
                                  duplicateProperty.Name,
                                  property.DeclaringEntityType.DisplayName(),
                                  property.Name,
                                  columnName,
                                  storeObject.DisplayName()));
                }

                break;
            }
        }
        /// <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>
        protected override void ValidateSharedColumnsCompatibility(
            IReadOnlyList <IEntityType> mappedTypes,
            StoreObjectIdentifier storeObject,
            IDiagnosticsLogger <DbLoggerCategory.Model.Validation> logger)
        {
            base.ValidateSharedColumnsCompatibility(mappedTypes, storeObject, logger);

            var identityColumns = new Dictionary <string, IProperty>();

            foreach (var property in mappedTypes.SelectMany(et => et.GetDeclaredProperties()))
            {
                if (property.GetValueGenerationStrategy(storeObject) == SqlServerValueGenerationStrategy.IdentityColumn)
                {
                    var columnName = property.GetColumnName(storeObject);
                    if (columnName == null)
                    {
                        continue;
                    }

                    identityColumns[columnName] = property;
                }
            }

            if (identityColumns.Count > 1)
            {
                var sb = new StringBuilder()
                         .AppendJoin(identityColumns.Values.Select(p => "'" + p.DeclaringEntityType.DisplayName() + "." + p.Name + "'"));
                throw new InvalidOperationException(SqlServerStrings.MultipleIdentityColumns(sb, storeObject.DisplayName()));
            }
        }