Skip to content

Commit

Permalink
Allow long identity seed
Browse files Browse the repository at this point in the history
Fixes #24840
  • Loading branch information
AndriySvyryd authored Jun 4, 2021
1 parent b141038 commit fa4b179
Show file tree
Hide file tree
Showing 7 changed files with 117 additions and 37 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -152,12 +152,12 @@ protected override bool IsHandledByConvention(IModel model, IAnnotation annotati
switch (strategy)
{
case SqlServerValueGenerationStrategy.IdentityColumn:
var seed = GetAndRemove<int?>(annotations, SqlServerAnnotationNames.IdentitySeed) ?? 1;
var seed = GetAndRemove<long?>(annotations, SqlServerAnnotationNames.IdentitySeed) ?? 1;
var increment = GetAndRemove<int?>(annotations, SqlServerAnnotationNames.IdentityIncrement) ?? 1;
return new(
onModel
? nameof(SqlServerModelBuilderExtensions.UseIdentityColumns)
: nameof(SqlServerPropertyBuilderExtensions.UseIdentityColumn),
? "UseIdentityColumns"
: "UseIdentityColumn",
(seed, increment) switch
{
(1, 1) => Array.Empty<object>(),
Expand Down
21 changes: 18 additions & 3 deletions src/EFCore.SqlServer/Extensions/SqlServerModelBuilderExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ public static bool CanSetHiLoSequence(
/// <returns> The same builder instance so that multiple calls can be chained. </returns>
public static ModelBuilder UseIdentityColumns(
this ModelBuilder modelBuilder,
int seed = 1,
long seed = 1,
int increment = 1)
{
Check.NotNull(modelBuilder, nameof(modelBuilder));
Expand All @@ -124,6 +124,21 @@ public static ModelBuilder UseIdentityColumns(
return modelBuilder;
}

/// <summary>
/// Configures the model to use the SQL Server IDENTITY feature to generate values for key properties
/// marked as <see cref="ValueGenerated.OnAdd" />, when targeting SQL Server. This is the default
/// behavior when targeting SQL Server.
/// </summary>
/// <param name="modelBuilder"> The model builder. </param>
/// <param name="seed"> The value that is used for the very first row loaded into the table. </param>
/// <param name="increment"> The incremental value that is added to the identity value of the previous row that was loaded. </param>
/// <returns> The same builder instance so that multiple calls can be chained. </returns>
public static ModelBuilder UseIdentityColumns(
this ModelBuilder modelBuilder,
int seed,
int increment = 1)
=> modelBuilder.UseIdentityColumns((long)seed, increment);

/// <summary>
/// Configures the default seed for SQL Server IDENTITY.
/// </summary>
Expand All @@ -136,7 +151,7 @@ public static ModelBuilder UseIdentityColumns(
/// </returns>
public static IConventionModelBuilder? HasIdentityColumnSeed(
this IConventionModelBuilder modelBuilder,
int? seed,
long? seed,
bool fromDataAnnotation = false)
{
if (modelBuilder.CanSetIdentityColumnSeed(seed, fromDataAnnotation))
Expand All @@ -157,7 +172,7 @@ public static ModelBuilder UseIdentityColumns(
/// <returns> <see langword="true" /> if the given value can be set as the seed for SQL Server IDENTITY. </returns>
public static bool CanSetIdentityColumnSeed(
this IConventionModelBuilder modelBuilder,
int? seed,
long? seed,
bool fromDataAnnotation = false)
{
Check.NotNull(modelBuilder, nameof(modelBuilder));
Expand Down
8 changes: 4 additions & 4 deletions src/EFCore.SqlServer/Extensions/SqlServerModelExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -121,17 +121,17 @@ public static void SetHiLoSequenceSchema(this IMutableModel model, string? value
/// </summary>
/// <param name="model"> The model. </param>
/// <returns> The default identity seed. </returns>
public static int GetIdentitySeed(this IReadOnlyModel model)
public static long GetIdentitySeed(this IReadOnlyModel model)
=> model is RuntimeModel
? throw new InvalidOperationException(CoreStrings.RuntimeModelMissingData)
: (int?)model[SqlServerAnnotationNames.IdentitySeed] ?? 1;
: (long?)model[SqlServerAnnotationNames.IdentitySeed] ?? 1;

/// <summary>
/// Sets the default identity seed.
/// </summary>
/// <param name="model"> The model. </param>
/// <param name="seed"> The value to set. </param>
public static void SetIdentitySeed(this IMutableModel model, int? seed)
public static void SetIdentitySeed(this IMutableModel model, long? seed)
=> model.SetOrRemoveAnnotation(
SqlServerAnnotationNames.IdentitySeed,
seed);
Expand All @@ -143,7 +143,7 @@ public static void SetIdentitySeed(this IMutableModel model, int? seed)
/// <param name="seed"> The value to set. </param>
/// <param name="fromDataAnnotation"> Indicates whether the configuration was specified using a data annotation. </param>
/// <returns> The configured value. </returns>
public static int? SetIdentitySeed(this IConventionModel model, int? seed, bool fromDataAnnotation = false)
public static long? SetIdentitySeed(this IConventionModel model, long? seed, bool fromDataAnnotation = false)
{
model.SetOrRemoveAnnotation(
SqlServerAnnotationNames.IdentitySeed,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ public static bool CanSetHiLoSequence(
/// <returns> The same builder instance so that multiple calls can be chained. </returns>
public static PropertyBuilder UseIdentityColumn(
this PropertyBuilder propertyBuilder,
int seed = 1,
long seed = 1,
int increment = 1)
{
Check.NotNull(propertyBuilder, nameof(propertyBuilder));
Expand All @@ -141,6 +141,20 @@ public static PropertyBuilder UseIdentityColumn(
return propertyBuilder;
}

/// <summary>
/// Configures the key property to use the SQL Server IDENTITY feature to generate values for new entities,
/// when targeting SQL Server. This method sets the property to be <see cref="ValueGenerated.OnAdd" />.
/// </summary>
/// <param name="propertyBuilder"> The builder for the property being configured. </param>
/// <param name="seed"> The value that is used for the very first row loaded into the table. </param>
/// <param name="increment"> The incremental value that is added to the identity value of the previous row that was loaded. </param>
/// <returns> The same builder instance so that multiple calls can be chained. </returns>
public static PropertyBuilder UseIdentityColumn(
this PropertyBuilder propertyBuilder,
int seed,
int increment = 1)
=> propertyBuilder.UseIdentityColumn((long)seed, increment);

/// <summary>
/// Configures the key property to use the SQL Server IDENTITY feature to generate values for new entities,
/// when targeting SQL Server. This method sets the property to be <see cref="ValueGenerated.OnAdd" />.
Expand All @@ -152,10 +166,25 @@ public static PropertyBuilder UseIdentityColumn(
/// <returns> The same builder instance so that multiple calls can be chained. </returns>
public static PropertyBuilder<TProperty> UseIdentityColumn<TProperty>(
this PropertyBuilder<TProperty> propertyBuilder,
int seed = 1,
long seed = 1,
int increment = 1)
=> (PropertyBuilder<TProperty>)UseIdentityColumn((PropertyBuilder)propertyBuilder, seed, increment);

/// <summary>
/// Configures the key property to use the SQL Server IDENTITY feature to generate values for new entities,
/// when targeting SQL Server. This method sets the property to be <see cref="ValueGenerated.OnAdd" />.
/// </summary>
/// <typeparam name="TProperty"> The type of the property being configured. </typeparam>
/// <param name="propertyBuilder"> The builder for the property being configured. </param>
/// <param name="seed"> The value that is used for the very first row loaded into the table. </param>
/// <param name="increment"> The incremental value that is added to the identity value of the previous row that was loaded. </param>
/// <returns> The same builder instance so that multiple calls can be chained. </returns>
public static PropertyBuilder<TProperty> UseIdentityColumn<TProperty>(
this PropertyBuilder<TProperty> propertyBuilder,
int seed,
int increment = 1)
=> (PropertyBuilder<TProperty>)UseIdentityColumn((PropertyBuilder)propertyBuilder, (long)seed, increment);

/// <summary>
/// Configures the seed for SQL Server IDENTITY.
/// </summary>
Expand All @@ -168,7 +197,7 @@ public static PropertyBuilder<TProperty> UseIdentityColumn<TProperty>(
/// </returns>
public static IConventionPropertyBuilder? HasIdentityColumnSeed(
this IConventionPropertyBuilder propertyBuilder,
int? seed,
long? seed,
bool fromDataAnnotation = false)
{
if (propertyBuilder.CanSetIdentityColumnSeed(seed, fromDataAnnotation))
Expand All @@ -189,7 +218,7 @@ public static PropertyBuilder<TProperty> UseIdentityColumn<TProperty>(
/// <returns> <see langword="true" /> if the given value can be set as the seed for SQL Server IDENTITY. </returns>
public static bool CanSetIdentityColumnSeed(
this IConventionPropertyBuilder propertyBuilder,
int? seed,
long? seed,
bool fromDataAnnotation = false)
{
Check.NotNull(propertyBuilder, nameof(propertyBuilder));
Expand Down
28 changes: 18 additions & 10 deletions src/EFCore.SqlServer/Extensions/SqlServerPropertyExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -204,18 +204,19 @@ public static void SetHiLoSequenceSchema(this IMutableProperty property, string?
/// </summary>
/// <param name="property"> The property. </param>
/// <returns> The identity seed. </returns>
public static int? GetIdentitySeed(this IReadOnlyProperty property)
public static long? GetIdentitySeed(this IReadOnlyProperty property)
=> property is RuntimeProperty
? throw new InvalidOperationException(CoreStrings.RuntimeModelMissingData)
: (int?)property[SqlServerAnnotationNames.IdentitySeed];
: (long?)property[SqlServerAnnotationNames.IdentitySeed]
?? property.DeclaringEntityType.Model.GetIdentitySeed();

/// <summary>
/// Returns the identity seed.
/// </summary>
/// <param name="property"> The property. </param>
/// <param name="storeObject"> The identifier of the store object. </param>
/// <returns> The identity seed. </returns>
public static int? GetIdentitySeed(this IReadOnlyProperty property, in StoreObjectIdentifier storeObject)
public static long? GetIdentitySeed(this IReadOnlyProperty property, in StoreObjectIdentifier storeObject)
{
if (property is RuntimeProperty)
{
Expand All @@ -225,18 +226,21 @@ public static void SetHiLoSequenceSchema(this IMutableProperty property, string?
var annotation = property.FindAnnotation(SqlServerAnnotationNames.IdentitySeed);
if (annotation != null)
{
return (int?)annotation.Value;
return (long?)annotation.Value;
}

return property.FindSharedStoreObjectRootProperty(storeObject)?.GetIdentitySeed(storeObject);
var sharedProperty = property.FindSharedStoreObjectRootProperty(storeObject);
return sharedProperty == null
? property.DeclaringEntityType.Model.GetIdentitySeed()
: sharedProperty.GetIdentitySeed(storeObject);
}

/// <summary>
/// Sets the identity seed.
/// </summary>
/// <param name="property"> The property. </param>
/// <param name="seed"> The value to set. </param>
public static void SetIdentitySeed(this IMutableProperty property, int? seed)
public static void SetIdentitySeed(this IMutableProperty property, long? seed)
=> property.SetOrRemoveAnnotation(
SqlServerAnnotationNames.IdentitySeed,
seed);
Expand All @@ -248,9 +252,9 @@ public static void SetIdentitySeed(this IMutableProperty property, int? seed)
/// <param name="seed"> The value to set. </param>
/// <param name="fromDataAnnotation"> Indicates whether the configuration was specified using a data annotation. </param>
/// <returns> The configured value. </returns>
public static int? SetIdentitySeed(
public static long? SetIdentitySeed(
this IConventionProperty property,
int? seed,
long? seed,
bool fromDataAnnotation = false)
{
property.SetOrRemoveAnnotation(
Expand All @@ -277,7 +281,8 @@ public static void SetIdentitySeed(this IMutableProperty property, int? seed)
public static int? GetIdentityIncrement(this IReadOnlyProperty property)
=> property is RuntimeProperty
? throw new InvalidOperationException(CoreStrings.RuntimeModelMissingData)
: (int?)property[SqlServerAnnotationNames.IdentityIncrement];
: (int?)property[SqlServerAnnotationNames.IdentityIncrement]
?? property.DeclaringEntityType.Model.GetIdentityIncrement();

/// <summary>
/// Returns the identity increment.
Expand All @@ -298,7 +303,10 @@ public static void SetIdentitySeed(this IMutableProperty property, int? seed)
return (int?)annotation.Value;
}

return property.FindSharedStoreObjectRootProperty(storeObject)?.GetIdentityIncrement(storeObject);
var sharedProperty = property.FindSharedStoreObjectRootProperty(storeObject);
return sharedProperty == null
? property.DeclaringEntityType.Model.GetIdentityIncrement()
: sharedProperty.GetIdentityIncrement(storeObject);
}

/// <summary>
Expand Down
Loading

0 comments on commit fa4b179

Please sign in to comment.