コード例 #1
0
        /// <summary>
        ///     Configures the default value generation strategy for key properties marked as <see cref="ValueGenerated.OnAdd" />,
        ///     when targeting SQL Server.
        /// </summary>
        /// <param name="modelBuilder"> The model builder. </param>
        /// <param name="valueGenerationStrategy"> The value generation strategy. </param>
        /// <param name="fromDataAnnotation"> Indicates whether the configuration was specified using a data annotation. </param>
        /// <returns>
        ///     The same builder instance if the configuration was applied,
        ///     <c>null</c> otherwise.
        /// </returns>
        public static IConventionModelBuilder HasValueGenerationStrategy(
            [NotNull] this IConventionModelBuilder modelBuilder,
            SqlServerValueGenerationStrategy?valueGenerationStrategy,
            bool fromDataAnnotation = false)
        {
            if (modelBuilder.CanSetValueGenerationStrategy(valueGenerationStrategy, fromDataAnnotation))
            {
                modelBuilder.Metadata.SetValueGenerationStrategy(valueGenerationStrategy, fromDataAnnotation);
                if (valueGenerationStrategy != SqlServerValueGenerationStrategy.IdentityColumn)
                {
                    modelBuilder.HasIdentityColumnSeed(null, fromDataAnnotation);
                    modelBuilder.HasIdentityColumnIncrement(null, fromDataAnnotation);
                }

                if (valueGenerationStrategy != SqlServerValueGenerationStrategy.SequenceHiLo)
                {
                    modelBuilder.HasHiLoSequence(null, null, fromDataAnnotation);
                }

                return(modelBuilder);
            }

            return(null);
        }
コード例 #2
0
        /// <summary>
        ///     This API supports the Entity Framework Core infrastructure and is not intended to be used
        ///     directly from your code. This API may change or be removed in future releases.
        /// </summary>
        public new virtual bool ValueGenerationStrategy(SqlServerValueGenerationStrategy?value)
        {
            if (value == null)
            {
                PropertyBuilder.ValueGenerated(ValueGenerated.Never, ConfigurationSource.Convention);
                PropertyBuilder.RequiresValueGenerator(false, ConfigurationSource.Convention);
                HiLoSequenceName(null);
                HiLoSequenceSchema(null);
            }
            else if (value.Value == SqlServerValueGenerationStrategy.IdentityColumn)
            {
                PropertyBuilder.ValueGenerated(ValueGenerated.OnAdd, ConfigurationSource.Convention);
                PropertyBuilder.RequiresValueGenerator(true, ConfigurationSource.Convention);
                HiLoSequenceName(null);
                HiLoSequenceSchema(null);
            }
            else if (value.Value == SqlServerValueGenerationStrategy.SequenceHiLo)
            {
                PropertyBuilder.ValueGenerated(ValueGenerated.OnAdd, ConfigurationSource.Convention);
                PropertyBuilder.RequiresValueGenerator(true, ConfigurationSource.Convention);
            }

            return(SetValueGenerationStrategy(value));
        }
コード例 #3
0
 protected virtual bool SetValueGenerationStrategy(SqlServerValueGenerationStrategy? value)
     => Annotations.SetAnnotation(SqlServerAnnotationNames.ValueGenerationStrategy, value);
 public static IConventionModelBuilder ForSqlServerHasValueGenerationStrategy(
     [NotNull] this IConventionModelBuilder modelBuilder,
     SqlServerValueGenerationStrategy?valueGenerationStrategy,
     bool fromDataAnnotation = false)
 => modelBuilder.HasValueGenerationStrategy(valueGenerationStrategy, fromDataAnnotation);
コード例 #5
0
 /// <summary>
 ///     This API supports the Entity Framework Core infrastructure and is not intended to be used
 ///     directly from your code. This API may change or be removed in future releases.
 /// </summary>
 public new virtual bool ValueGenerationStrategy(SqlServerValueGenerationStrategy?value) => SetValueGenerationStrategy(value);
コード例 #6
0
 /// <summary>
 ///     Sets the <see cref="SqlServerValueGenerationStrategy" /> to use for properties
 ///     of keys in the model that don't have a strategy explicitly set.
 /// </summary>
 /// <param name="model"> The model. </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 SetValueGenerationStrategy(
     [NotNull] this IConventionModel model, SqlServerValueGenerationStrategy?value, bool fromDataAnnotation = false)
 => model.SetOrRemoveAnnotation(SqlServerAnnotationNames.ValueGenerationStrategy, value, fromDataAnnotation);
コード例 #7
0
 /// <summary>
 ///     Sets the <see cref="SqlServerValueGenerationStrategy" /> to use for properties
 ///     of keys in the model that don't have a strategy explicitly set.
 /// </summary>
 /// <param name="model"> The model. </param>
 /// <param name="value"> The value to set. </param>
 public static void SetValueGenerationStrategy([NotNull] this IMutableModel model, SqlServerValueGenerationStrategy?value)
 => model.SetOrRemoveAnnotation(SqlServerAnnotationNames.ValueGenerationStrategy, value);
コード例 #8
0
        private static void CheckSqlServerValueGenerationStrategy(IProperty property, SqlServerValueGenerationStrategy?value)
        {
            if (value != null)
            {
                var propertyType = property.ClrType;

                if (value == SqlServerValueGenerationStrategy.IdentityColumn &&
                    !IsCompatibleWithValueGeneration(property))
                {
                    throw new ArgumentException(
                              SqlServerStrings.IdentityBadType(
                                  property.Name, property.DeclaringEntityType.DisplayName(), propertyType.ShortDisplayName()));
                }

                if (value == SqlServerValueGenerationStrategy.SequenceHiLo &&
                    !IsCompatibleWithValueGeneration(property))
                {
                    throw new ArgumentException(
                              SqlServerStrings.SequenceBadType(
                                  property.Name, property.DeclaringEntityType.DisplayName(), propertyType.ShortDisplayName()));
                }
            }
        }
コード例 #9
0
        /// <inheritdoc />
        public virtual void ProcessModelFinalizing(
            IConventionModelBuilder modelBuilder,
            IConventionContext <IConventionModelBuilder> context)
        {
            foreach (var entityType in modelBuilder.Metadata.GetEntityTypes())
            {
                foreach (var property in entityType.GetDeclaredProperties())
                {
                    SqlServerValueGenerationStrategy?strategy = null;
                    var table = entityType.GetTableName();
                    if (table != null)
                    {
                        var storeObject = StoreObjectIdentifier.Table(table, entityType.GetSchema());
                        strategy = property.GetValueGenerationStrategy(storeObject, Dependencies.TypeMappingSource);
                        if (strategy == SqlServerValueGenerationStrategy.None &&
                            !IsStrategyNoneNeeded(property, storeObject))
                        {
                            strategy = null;
                        }
                    }
                    else
                    {
                        var view = entityType.GetViewName();
                        if (view != null)
                        {
                            var storeObject = StoreObjectIdentifier.View(view, entityType.GetViewSchema());
                            strategy = property.GetValueGenerationStrategy(storeObject, Dependencies.TypeMappingSource);
                            if (strategy == SqlServerValueGenerationStrategy.None &&
                                !IsStrategyNoneNeeded(property, storeObject))
                            {
                                strategy = null;
                            }
                        }
                    }

                    // Needed for the annotation to show up in the model snapshot
                    if (strategy != null)
                    {
                        property.Builder.HasValueGenerationStrategy(strategy);
                    }
                }
            }

            bool IsStrategyNoneNeeded(IReadOnlyProperty property, StoreObjectIdentifier storeObject)
            {
                if (property.ValueGenerated == ValueGenerated.OnAdd &&
                    !property.TryGetDefaultValue(storeObject, out _) &&
                    property.GetDefaultValueSql(storeObject) == null &&
                    property.GetComputedColumnSql(storeObject) == null &&
                    property.DeclaringEntityType.Model.GetValueGenerationStrategy() == SqlServerValueGenerationStrategy.IdentityColumn)
                {
                    var providerClrType = (property.GetValueConverter()
                                           ?? (property.FindRelationalTypeMapping(storeObject)
                                               ?? Dependencies.TypeMappingSource.FindMapping((IProperty)property))?.Converter)
                                          ?.ProviderClrType.UnwrapNullableType();

                    return(providerClrType != null &&
                           (providerClrType.IsInteger() || providerClrType == typeof(decimal)));
                }

                return(false);
            }
        }
コード例 #10
0
 protected virtual bool SetValueGenerationStrategy(SqlServerValueGenerationStrategy?value)
 => Annotations.SetAnnotation(SqlServerFullAnnotationNames.Instance.ValueGenerationStrategy,
                              null,
                              value);
コード例 #11
0
 /// <summary>
 ///     Returns a value indicating whether the given value can be set as the default value generation strategy.
 /// </summary>
 /// <remarks>
 ///     See <see href="https://aka.ms/efcore-docs-modeling">Modeling entity types and relationships</see>, and
 ///     <see href="https://aka.ms/efcore-docs-sqlserver">Accessing SQL Server and SQL Azure databases with EF Core</see>
 ///     for more information.
 /// </remarks>
 /// <param name="modelBuilder">The model builder.</param>
 /// <param name="valueGenerationStrategy">The value generation strategy.</param>
 /// <param name="fromDataAnnotation">Indicates whether the configuration was specified using a data annotation.</param>
 /// <returns><see langword="true" /> if the given value can be set as the default value generation strategy.</returns>
 public static bool CanSetValueGenerationStrategy(
     this IConventionModelBuilder modelBuilder,
     SqlServerValueGenerationStrategy?valueGenerationStrategy,
     bool fromDataAnnotation = false)
 => modelBuilder.CanSetAnnotation(
     SqlServerAnnotationNames.ValueGenerationStrategy, valueGenerationStrategy, fromDataAnnotation);
コード例 #12
0
        private static void CheckValueGenerationStrategy<TDatabaseClrType>(IProperty property, SqlServerValueGenerationStrategy? value)
        {
            if (value != null)
            {
                //var propertyType = property.ClrType;
                //var propertyType = property.GetRelationalTypeMapping()?.Converter?.ProviderClrType ?? property.ClrType;
                var propertyType = typeof(TDatabaseClrType);

                if (value == SqlServerValueGenerationStrategy.IdentityColumn
                    && !IsCompatibleWithValueGeneration<TDatabaseClrType>(property))
                {
                    throw new ArgumentException(
                        SqlServerStrings.IdentityBadType(
                            property.Name, property.DeclaringEntityType.DisplayName(), propertyType.ShortDisplayName()));
                }

                if (value == SqlServerValueGenerationStrategy.SequenceHiLo
                    && !IsCompatibleWithValueGeneration<TDatabaseClrType>(property))
                {
                    throw new ArgumentException(
                        SqlServerStrings.SequenceBadType(
                            property.Name, property.DeclaringEntityType.DisplayName(), propertyType.ShortDisplayName()));
                }
            }
        }