/// <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); }
/// <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)); }
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);
/// <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);
/// <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);
/// <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);
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())); } } }
/// <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); } }
protected virtual bool SetValueGenerationStrategy(SqlServerValueGenerationStrategy?value) => Annotations.SetAnnotation(SqlServerFullAnnotationNames.Instance.ValueGenerationStrategy, null, value);
/// <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);
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())); } } }