diff --git a/src/EFCore.Relational/Update/AffectedCountModificationCommandBatch.cs b/src/EFCore.Relational/Update/AffectedCountModificationCommandBatch.cs index bb0315d088e..5edd4fac4fe 100644 --- a/src/EFCore.Relational/Update/AffectedCountModificationCommandBatch.cs +++ b/src/EFCore.Relational/Update/AffectedCountModificationCommandBatch.cs @@ -1,8 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Data; - namespace Microsoft.EntityFrameworkCore.Update; /// @@ -23,8 +21,9 @@ public abstract class AffectedCountModificationCommandBatch : ReaderModification /// Creates a new instance. /// /// Service dependencies. - protected AffectedCountModificationCommandBatch(ModificationCommandBatchFactoryDependencies dependencies) - : base(dependencies) + /// The maximum batch size. Defaults to 1000. + protected AffectedCountModificationCommandBatch(ModificationCommandBatchFactoryDependencies dependencies, int? maxBatchSize = null) + : base(dependencies, maxBatchSize) { } diff --git a/src/EFCore.Relational/Update/ReaderModificationCommandBatch.cs b/src/EFCore.Relational/Update/ReaderModificationCommandBatch.cs index 8fdfd66fc4b..909a2496467 100644 --- a/src/EFCore.Relational/Update/ReaderModificationCommandBatch.cs +++ b/src/EFCore.Relational/Update/ReaderModificationCommandBatch.cs @@ -33,7 +33,8 @@ public abstract class ReaderModificationCommandBatch : ModificationCommandBatch /// Creates a new instance. /// /// Service dependencies. - protected ReaderModificationCommandBatch(ModificationCommandBatchFactoryDependencies dependencies) + /// The maximum batch size. Defaults to 1000. + protected ReaderModificationCommandBatch(ModificationCommandBatchFactoryDependencies dependencies, int? maxBatchSize = null) { Dependencies = dependencies; @@ -42,6 +43,8 @@ protected ReaderModificationCommandBatch(ModificationCommandBatchFactoryDependen UpdateSqlGenerator = dependencies.UpdateSqlGenerator; UpdateSqlGenerator.AppendBatchHeader(SqlBuilder); _batchHeaderLength = SqlBuilder.Length; + + MaxBatchSize = maxBatchSize ?? 1000; } /// @@ -62,8 +65,7 @@ protected ReaderModificationCommandBatch(ModificationCommandBatchFactoryDependen /// /// The maximum number of instances that can be added to a single batch. /// - protected virtual int MaxBatchSize - => 1000; + protected virtual int MaxBatchSize { get; } /// /// Gets the command text builder for the commands in the batch. diff --git a/src/EFCore.Relational/Update/SingularModificationCommandBatch.cs b/src/EFCore.Relational/Update/SingularModificationCommandBatch.cs index e63dd91c95f..5ec62765795 100644 --- a/src/EFCore.Relational/Update/SingularModificationCommandBatch.cs +++ b/src/EFCore.Relational/Update/SingularModificationCommandBatch.cs @@ -23,13 +23,7 @@ public class SingularModificationCommandBatch : AffectedCountModificationCommand /// /// Service dependencies. public SingularModificationCommandBatch(ModificationCommandBatchFactoryDependencies dependencies) - : base(dependencies) + : base(dependencies, maxBatchSize: 1) { } - - /// - /// The maximum number of instances that can be added to a single batch; always returns 1. - /// - protected override int MaxBatchSize - => 1; } diff --git a/src/EFCore.Relational/Update/UpdateSqlGenerator.cs b/src/EFCore.Relational/Update/UpdateSqlGenerator.cs index 8676a9752bd..3a8c9cde012 100644 --- a/src/EFCore.Relational/Update/UpdateSqlGenerator.cs +++ b/src/EFCore.Relational/Update/UpdateSqlGenerator.cs @@ -134,7 +134,7 @@ protected virtual ResultSetMapping AppendUpdateReturningOperation( AppendUpdateCommand( commandStringBuilder, name, schema, writeOperations, readOperations, conditionOperations, - additionalReadValues: readOperations.Count == 0 ? "1" : null); + appendReturningOneClause: readOperations.Count == 0); return ResultSetMapping.LastInResultSet; } @@ -175,7 +175,7 @@ protected virtual ResultSetMapping AppendDeleteReturningOperation( requiresTransaction = false; AppendDeleteCommand( - commandStringBuilder, name, schema, Array.Empty(), conditionOperations, additionalReadValues: "1"); + commandStringBuilder, name, schema, Array.Empty(), conditionOperations, appendReturningOneClause: true); return ResultSetMapping.LastInResultSet; } @@ -211,7 +211,7 @@ protected virtual void AppendInsertCommand( /// The operations for each column. /// The operations for column values to be read back. /// The operations used to generate the WHERE clause for the update. - /// Additional values to be read back. + /// Whether to append an additional constant of 1 to be read back. protected virtual void AppendUpdateCommand( StringBuilder commandStringBuilder, string name, @@ -219,11 +219,11 @@ protected virtual void AppendUpdateCommand( IReadOnlyList writeOperations, IReadOnlyList readOperations, IReadOnlyList conditionOperations, - string? additionalReadValues = null) + bool appendReturningOneClause = false) { AppendUpdateCommandHeader(commandStringBuilder, name, schema, writeOperations); AppendWhereClause(commandStringBuilder, conditionOperations); - AppendReturningClause(commandStringBuilder, readOperations, additionalReadValues); + AppendReturningClause(commandStringBuilder, readOperations, appendReturningOneClause ? "1" : null); commandStringBuilder.AppendLine(SqlGenerationHelper.StatementTerminator); } @@ -235,18 +235,18 @@ protected virtual void AppendUpdateCommand( /// The table schema, or to use the default schema. /// The operations for column values to be read back. /// The operations used to generate the WHERE clause for the delete. - /// Additional values to be read back. + /// Whether to append an additional constant of 1 to be read back. protected virtual void AppendDeleteCommand( StringBuilder commandStringBuilder, string name, string? schema, IReadOnlyList readOperations, IReadOnlyList conditionOperations, - string? additionalReadValues = null) + bool appendReturningOneClause = false) { AppendDeleteCommandHeader(commandStringBuilder, name, schema); AppendWhereClause(commandStringBuilder, conditionOperations); - AppendReturningClause(commandStringBuilder, readOperations, additionalReadValues); + AppendReturningClause(commandStringBuilder, readOperations, appendReturningOneClause ? "1" : null); commandStringBuilder.AppendLine(SqlGenerationHelper.StatementTerminator); } @@ -478,7 +478,7 @@ protected virtual void AppendReturningClause( commandStringBuilder.Append(", "); } - commandStringBuilder.Append(additionalValues); + commandStringBuilder.Append("1"); } } } diff --git a/src/EFCore.SqlServer/Update/Internal/SqlServerModificationCommandBatch.cs b/src/EFCore.SqlServer/Update/Internal/SqlServerModificationCommandBatch.cs index e26533d030b..85b8dbf0381 100644 --- a/src/EFCore.SqlServer/Update/Internal/SqlServerModificationCommandBatch.cs +++ b/src/EFCore.SqlServer/Update/Internal/SqlServerModificationCommandBatch.cs @@ -29,8 +29,9 @@ public class SqlServerModificationCommandBatch : AffectedCountModificationComman public SqlServerModificationCommandBatch( ModificationCommandBatchFactoryDependencies dependencies, int maxBatchSize) - : base(dependencies) - => MaxBatchSize = maxBatchSize; + : base(dependencies, maxBatchSize) + { + } /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -41,14 +42,6 @@ public SqlServerModificationCommandBatch( protected new virtual ISqlServerUpdateSqlGenerator UpdateSqlGenerator => (ISqlServerUpdateSqlGenerator)base.UpdateSqlGenerator; - /// - /// The maximum number of instances that can be added to a single batch. - /// - /// - /// For SQL Server, this is 42 by default, and cannot exceed 1000. - /// - protected override int MaxBatchSize { get; } - /// /// 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 diff --git a/src/EFCore.SqlServer/Update/Internal/SqlServerUpdateSqlGenerator.cs b/src/EFCore.SqlServer/Update/Internal/SqlServerUpdateSqlGenerator.cs index dbeedad814b..4ae6e84480c 100644 --- a/src/EFCore.SqlServer/Update/Internal/SqlServerUpdateSqlGenerator.cs +++ b/src/EFCore.SqlServer/Update/Internal/SqlServerUpdateSqlGenerator.cs @@ -126,11 +126,11 @@ protected override void AppendUpdateCommand( IReadOnlyList writeOperations, IReadOnlyList readOperations, IReadOnlyList conditionOperations, - string? additionalReadValues = null) + bool appendReturningOneClause = false) { // In SQL Server the OUTPUT clause is placed differently (before the WHERE instead of at the end) AppendUpdateCommandHeader(commandStringBuilder, name, schema, writeOperations); - AppendOutputClause(commandStringBuilder, readOperations, additionalReadValues); + AppendOutputClause(commandStringBuilder, readOperations, appendReturningOneClause ? "1" : null); AppendWhereClause(commandStringBuilder, conditionOperations); commandStringBuilder.AppendLine(SqlGenerationHelper.StatementTerminator); } @@ -166,11 +166,11 @@ protected override void AppendDeleteCommand( string? schema, IReadOnlyList readOperations, IReadOnlyList conditionOperations, - string? additionalReadValues = null) + bool appendReturningOneClause = false) { // In SQL Server the OUTPUT clause is placed differently (before the WHERE instead of at the end) AppendDeleteCommandHeader(commandStringBuilder, name, schema); - AppendOutputClause(commandStringBuilder, readOperations, additionalReadValues); + AppendOutputClause(commandStringBuilder, readOperations, appendReturningOneClause ? "1" : null); AppendWhereClause(commandStringBuilder, conditionOperations); commandStringBuilder.AppendLine(SqlGenerationHelper.StatementTerminator); }