From 9d5c4edc7482b2df1f72837c90de3bc559eae06e Mon Sep 17 00:00:00 2001 From: Edward Neal <55035479+edwardneal@users.noreply.github.com> Date: Sun, 1 Feb 2026 23:21:46 +0000 Subject: [PATCH 1/4] Publicly expose SqlBatch* types on netfx and enable tests APIs not exposed: * SqlClientFactory.CanCreateBatch * SqlClientFactory.CreateBatch * SqlClientFactory.CreateBatchCommand * SqlConnection.CanCreateBatch * SqlConnection.CreateBatch --- .../netcore/ref/Microsoft.Data.SqlClient.cs | 8 - .../ref/Microsoft.Data.SqlClient.csproj | 3 - .../src/Microsoft.Data.SqlClient.csproj | 3 - .../netfx/ref/Microsoft.Data.SqlClient.csproj | 1 + .../netfx/src/Microsoft.Data.SqlClient.csproj | 6 + ...crosoft.Data.SqlClient.Batch.NetCoreApp.cs | 29 --- .../ref/Microsoft.Data.SqlClient.Batch.cs | 188 ++++++++++++++---- .../src/Microsoft/Data/SqlClient/SqlBatch.cs | 166 +++++++++++++--- .../Data/SqlClient/SqlBatchCommand.cs | 44 ++-- .../Data/SqlClient/SqlBatchCommand.netcore.cs | 21 -- .../SqlClient/SqlBatchCommandCollection.cs | 116 +++++++---- .../Data/SqlClient/SqlCommand.Scalar.cs | 2 - .../Microsoft/Data/SqlClient/SqlException.cs | 13 +- ....Data.SqlClient.ManualTesting.Tests.csproj | 4 +- .../tests/ManualTests/SQL/Batch/BatchTests.cs | 22 +- 15 files changed, 435 insertions(+), 191 deletions(-) delete mode 100644 src/Microsoft.Data.SqlClient/ref/Microsoft.Data.SqlClient.Batch.NetCoreApp.cs delete mode 100644 src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlBatchCommand.netcore.cs diff --git a/src/Microsoft.Data.SqlClient/netcore/ref/Microsoft.Data.SqlClient.cs b/src/Microsoft.Data.SqlClient/netcore/ref/Microsoft.Data.SqlClient.cs index 0a04d047f8..adb6bb3314 100644 --- a/src/Microsoft.Data.SqlClient/netcore/ref/Microsoft.Data.SqlClient.cs +++ b/src/Microsoft.Data.SqlClient/netcore/ref/Microsoft.Data.SqlClient.cs @@ -477,14 +477,6 @@ internal SqlClientFactory() { } public override System.Data.Common.DbParameter CreateParameter() { throw null; } /// public override System.Data.Common.DbDataSourceEnumerator CreateDataSourceEnumerator() { throw null; } -#if NET - /// - public override bool CanCreateBatch { get { throw null; } } - /// - public override System.Data.Common.DbBatch CreateBatch() { throw null; } - /// - public override System.Data.Common.DbBatchCommand CreateBatchCommand() { throw null; } -#endif } /// public partial class SqlClientLogger diff --git a/src/Microsoft.Data.SqlClient/netcore/ref/Microsoft.Data.SqlClient.csproj b/src/Microsoft.Data.SqlClient/netcore/ref/Microsoft.Data.SqlClient.csproj index a2751a6e57..7e9a20b2ca 100644 --- a/src/Microsoft.Data.SqlClient/netcore/ref/Microsoft.Data.SqlClient.csproj +++ b/src/Microsoft.Data.SqlClient/netcore/ref/Microsoft.Data.SqlClient.csproj @@ -27,10 +27,7 @@ - - - diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj index bbbf05277b..3c1ce7853e 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj @@ -665,9 +665,6 @@ Microsoft\Data\SqlClient\SqlBatchCommand.cs - - Microsoft\Data\SqlClient\SqlBatchCommand.netcore.cs - Microsoft\Data\SqlClient\SqlBatchCommandCollection.cs diff --git a/src/Microsoft.Data.SqlClient/netfx/ref/Microsoft.Data.SqlClient.csproj b/src/Microsoft.Data.SqlClient/netfx/ref/Microsoft.Data.SqlClient.csproj index 2735cce404..1759a61180 100644 --- a/src/Microsoft.Data.SqlClient/netfx/ref/Microsoft.Data.SqlClient.csproj +++ b/src/Microsoft.Data.SqlClient/netfx/ref/Microsoft.Data.SqlClient.csproj @@ -20,6 +20,7 @@ + diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj index 51e301a835..2109453adb 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj @@ -657,9 +657,15 @@ Microsoft\Data\SqlClient\SqlAuthenticationToken.cs + + Microsoft\Data\SqlClient\SqlBatch.cs + Microsoft\Data\SqlClient\SqlBatchCommand.cs + + Microsoft\Data\SqlClient\SqlBatchCommandCollection.cs + Microsoft\Data\SqlClient\SqlBuffer.cs diff --git a/src/Microsoft.Data.SqlClient/ref/Microsoft.Data.SqlClient.Batch.NetCoreApp.cs b/src/Microsoft.Data.SqlClient/ref/Microsoft.Data.SqlClient.Batch.NetCoreApp.cs deleted file mode 100644 index a693a7f9c1..0000000000 --- a/src/Microsoft.Data.SqlClient/ref/Microsoft.Data.SqlClient.Batch.NetCoreApp.cs +++ /dev/null @@ -1,29 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -namespace Microsoft.Data.SqlClient -{ - /// - public partial class SqlBatchCommand - { - /// - public Microsoft.Data.SqlClient.SqlCommandColumnEncryptionSetting ColumnEncryptionSetting { get { throw null; } set { } } - } - - /// - public partial class SqlConnection - { - /// - public override bool CanCreateBatch { get { throw null; } } - /// - protected override System.Data.Common.DbBatch CreateDbBatch() => throw null; - } - - /// - public partial class SqlException - { - /// - protected override System.Data.Common.DbBatchCommand DbBatchCommand => throw null; - } -} diff --git a/src/Microsoft.Data.SqlClient/ref/Microsoft.Data.SqlClient.Batch.cs b/src/Microsoft.Data.SqlClient/ref/Microsoft.Data.SqlClient.Batch.cs index 411c88a7f2..48961940d7 100644 --- a/src/Microsoft.Data.SqlClient/ref/Microsoft.Data.SqlClient.Batch.cs +++ b/src/Microsoft.Data.SqlClient/ref/Microsoft.Data.SqlClient.Batch.cs @@ -5,31 +5,31 @@ namespace Microsoft.Data.SqlClient { /// - public class SqlBatch : System.Data.Common.DbBatch + public class SqlBatch : + #if NET + System.Data.Common.DbBatch + #else + System.IDisposable, System.IAsyncDisposable + #endif { - /// - public SqlBatch() { throw null; } - /// - public SqlBatch(Microsoft.Data.SqlClient.SqlConnection connection, Microsoft.Data.SqlClient.SqlTransaction transaction = null) { throw null; } + #if NET /// - public override int Timeout { get => throw null; set { } } - /// - public System.Collections.Generic.List Commands { get { throw null; } } + public override int Timeout { get => throw null; set { } } /// public new Microsoft.Data.SqlClient.SqlConnection Connection { get => throw null; set { } } /// public new Microsoft.Data.SqlClient.SqlTransaction Transaction { get => throw null; set { } } /// - public new SqlBatchCommandCollection BatchCommands { get => throw null; } + public new Microsoft.Data.SqlClient.SqlBatchCommandCollection BatchCommands { get => throw null; } /// protected override System.Data.Common.DbBatchCommandCollection DbBatchCommands { get => throw null; } /// protected override System.Data.Common.DbConnection DbConnection { get => throw null; set { } } /// - protected override System.Data.Common.DbTransaction DbTransaction { get => throw null; set { } } + protected override System.Data.Common.DbTransaction DbTransaction { get => throw null; set { } } /// public override void Cancel() => throw null; - /// + /// protected override System.Data.Common.DbBatchCommand CreateDbBatchCommand() => throw null; /// public override void Dispose() => throw null; @@ -41,8 +41,6 @@ public class SqlBatch : System.Data.Common.DbBatch public override int ExecuteNonQuery() => throw null; /// public override System.Threading.Tasks.Task ExecuteNonQueryAsync(System.Threading.CancellationToken cancellationToken = default) => throw null; - /// - public Microsoft.Data.SqlClient.SqlDataReader ExecuteReader() => throw null; /// public new System.Threading.Tasks.Task ExecuteReaderAsync(System.Threading.CancellationToken cancellationToken = default) => throw null; /// @@ -53,79 +51,195 @@ public class SqlBatch : System.Data.Common.DbBatch public override void Prepare() => throw null; /// public override System.Threading.Tasks.Task PrepareAsync(System.Threading.CancellationToken cancellationToken = default) => throw null; +#else + /// + public int Timeout { get => throw null; set { } } + /// + public Microsoft.Data.SqlClient.SqlConnection Connection { get => throw null; set { } } + /// + public Microsoft.Data.SqlClient.SqlTransaction Transaction { get => throw null; set { } } + /// + public Microsoft.Data.SqlClient.SqlBatchCommandCollection BatchCommands { get => throw null; } + /// + protected virtual System.Data.Common.DbConnection DbConnection { get => throw null; set { } } + /// + protected virtual System.Data.Common.DbTransaction DbTransaction { get => throw null; set { } } + /// + public void Cancel() => throw null; + /// + public void Dispose() => throw null; + /// + protected virtual System.Data.Common.DbDataReader ExecuteDbDataReader(System.Data.CommandBehavior behavior) => throw null; + /// + protected virtual System.Threading.Tasks.Task ExecuteDbDataReaderAsync(System.Data.CommandBehavior behavior, System.Threading.CancellationToken cancellationToken) => throw null; + /// + public int ExecuteNonQuery() => throw null; + /// + public System.Threading.Tasks.Task ExecuteNonQueryAsync(System.Threading.CancellationToken cancellationToken = default) => throw null; + /// + public System.Threading.Tasks.Task ExecuteReaderAsync(System.Threading.CancellationToken cancellationToken = default) => throw null; + /// + public object ExecuteScalar() => throw null; + /// + public System.Threading.Tasks.Task ExecuteScalarAsync(System.Threading.CancellationToken cancellationToken = default) => throw null; + /// + public void Prepare() => throw null; + /// + public System.Threading.Tasks.Task PrepareAsync(System.Threading.CancellationToken cancellationToken = default) => throw null; + /// + public virtual System.Threading.Tasks.ValueTask DisposeAsync() => throw null; +#endif + /// + public SqlBatch() { throw null; } + /// + public SqlBatch(Microsoft.Data.SqlClient.SqlConnection connection, Microsoft.Data.SqlClient.SqlTransaction transaction = null) { throw null; } + /// + public System.Collections.Generic.List Commands { get { throw null; } } + /// + public Microsoft.Data.SqlClient.SqlDataReader ExecuteReader() => throw null; } /// - public partial class SqlBatchCommand : System.Data.Common.DbBatchCommand + public class SqlBatchCommand + #if NET + : System.Data.Common.DbBatchCommand + #endif { - /// - public SqlBatchCommand() => throw null; - /// - public SqlBatchCommand(string commandText, System.Data.CommandType commandType = System.Data.CommandType.Text, System.Collections.Generic.IEnumerable parameters = null, Microsoft.Data.SqlClient.SqlCommandColumnEncryptionSetting columnEncryptionSetting = Microsoft.Data.SqlClient.SqlCommandColumnEncryptionSetting.UseConnectionSetting) { throw null; } + #if NET /// public new Microsoft.Data.SqlClient.SqlParameterCollection Parameters { get { throw null; } } + /// + public override bool CanCreateParameter => throw null; /// public override string CommandText { get { throw null; } set { } } /// public override System.Data.CommandType CommandType { get { throw null; } set { } } - /// - public System.Data.CommandBehavior CommandBehavior { get { throw null; } set { } } /// public override int RecordsAffected { get { throw null; } } /// protected override System.Data.Common.DbParameterCollection DbParameterCollection => throw null; + /// + public override System.Data.Common.DbParameter CreateParameter() => throw null; + #else + /// + public Microsoft.Data.SqlClient.SqlParameterCollection Parameters { get { throw null; } } + /// + public bool CanCreateParameter => throw null; + /// + public string CommandText { get { throw null; } set { } } + /// + public System.Data.CommandType CommandType { get { throw null; } set { } } + /// + public int RecordsAffected { get { throw null; } } + /// + protected virtual System.Data.Common.DbParameterCollection DbParameterCollection => throw null; + /// + public System.Data.Common.DbParameter CreateParameter() => throw null; + #endif + /// + public SqlBatchCommand() => throw null; + /// + public SqlBatchCommand(string commandText, System.Data.CommandType commandType = System.Data.CommandType.Text, System.Collections.Generic.IEnumerable parameters = null, Microsoft.Data.SqlClient.SqlCommandColumnEncryptionSetting columnEncryptionSetting = Microsoft.Data.SqlClient.SqlCommandColumnEncryptionSetting.UseConnectionSetting) { throw null; } + /// + public Microsoft.Data.SqlClient.SqlCommandColumnEncryptionSetting ColumnEncryptionSetting { get { throw null; } set { } } + /// + public System.Data.CommandBehavior CommandBehavior { get { throw null; } set { } } } /// - public class SqlBatchCommandCollection : System.Data.Common.DbBatchCommandCollection, System.Collections.Generic.IList + public class SqlBatchCommandCollection : + #if NET + System.Data.Common.DbBatchCommandCollection, + #endif + System.Collections.Generic.IList { + #if NET /// public override int Count => throw null; /// public override bool IsReadOnly => throw null; - System.Collections.Generic.IEnumerator System.Collections.Generic.IEnumerable.GetEnumerator() => throw null; /// public override System.Collections.Generic.IEnumerator GetEnumerator() => throw null; - /// - public void Add(Microsoft.Data.SqlClient.SqlBatchCommand item) => throw null; /// public override void Add(System.Data.Common.DbBatchCommand item) => throw null; /// public override void Clear() => throw null; - /// - public bool Contains(Microsoft.Data.SqlClient.SqlBatchCommand item) => throw null; /// public override bool Contains(System.Data.Common.DbBatchCommand item) => throw null; - /// - public void CopyTo(Microsoft.Data.SqlClient.SqlBatchCommand[] array, int arrayIndex) => throw null; /// public override void CopyTo(System.Data.Common.DbBatchCommand[] array, int arrayIndex) => throw null; - /// - public int IndexOf(Microsoft.Data.SqlClient.SqlBatchCommand item) => throw null; /// public override int IndexOf(System.Data.Common.DbBatchCommand item) => throw null; - /// - public void Insert(int index, Microsoft.Data.SqlClient.SqlBatchCommand item) => throw null; /// public override void Insert(int index, System.Data.Common.DbBatchCommand item) => throw null; - /// - public bool Remove(Microsoft.Data.SqlClient.SqlBatchCommand item) => throw null; /// public override bool Remove(System.Data.Common.DbBatchCommand item) => throw null; /// public override void RemoveAt(int index) => throw null; - /// - Microsoft.Data.SqlClient.SqlBatchCommand System.Collections.Generic.IList.this[int index] { get => throw null; set { } } /// public new Microsoft.Data.SqlClient.SqlBatchCommand this[int index] { get => throw null; set { } } - System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => throw null; /// protected override System.Data.Common.DbBatchCommand GetBatchCommand(int index) => throw null; /// protected override void SetBatchCommand(int index, System.Data.Common.DbBatchCommand batchCommand) => throw null; + #else + /// + public int Count => throw null; + /// + public bool IsReadOnly => throw null; + /// + public void Clear() => throw null; + /// + public void RemoveAt(int index) => throw null; + /// + public Microsoft.Data.SqlClient.SqlBatchCommand this[int index] { get => throw null; set { } } + System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => throw null; + #endif + System.Collections.Generic.IEnumerator System.Collections.Generic.IEnumerable.GetEnumerator() => throw null; + /// + public void Add(Microsoft.Data.SqlClient.SqlBatchCommand item) => throw null; + /// + public bool Contains(Microsoft.Data.SqlClient.SqlBatchCommand item) => throw null; + /// + public void CopyTo(Microsoft.Data.SqlClient.SqlBatchCommand[] array, int arrayIndex) => throw null; + /// + public int IndexOf(Microsoft.Data.SqlClient.SqlBatchCommand item) => throw null; + /// + public void Insert(int index, Microsoft.Data.SqlClient.SqlBatchCommand item) => throw null; + /// + public bool Remove(Microsoft.Data.SqlClient.SqlBatchCommand item) => throw null; + /// + Microsoft.Data.SqlClient.SqlBatchCommand System.Collections.Generic.IList.this[int index] { get => throw null; set { } } + } + /// + public sealed partial class SqlClientFactory + { + #if NET + /// + public override bool CanCreateBatch { get { throw null; } } + /// + public override System.Data.Common.DbBatch CreateBatch() { throw null; } + /// + public override System.Data.Common.DbBatchCommand CreateBatchCommand() { throw null; } + #endif + } + /// + public sealed partial class SqlConnection + { + #if NET + /// + public override bool CanCreateBatch { get { throw null; } } + /// + protected override System.Data.Common.DbBatch CreateDbBatch() => throw null; + #endif } /// public sealed partial class SqlException { + #if NET /// public new Microsoft.Data.SqlClient.SqlBatchCommand BatchCommand { get { throw null; } } + #else + /// + public Microsoft.Data.SqlClient.SqlBatchCommand BatchCommand { get { throw null; } } + #endif } } diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlBatch.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlBatch.cs index 7171bdbfe3..30ca4a73dc 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlBatch.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlBatch.cs @@ -2,8 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#if NET - using System; using System.Collections.Generic; using System.Data; @@ -15,7 +13,12 @@ namespace Microsoft.Data.SqlClient { /// - public class SqlBatch : DbBatch + public class SqlBatch : + #if NET + DbBatch + #else + IDisposable, IAsyncDisposable + #endif { private SqlCommand _batchCommand; private List _commands; @@ -33,8 +36,28 @@ public SqlBatch(SqlConnection connection = null, SqlTransaction transaction = nu Connection = connection; Transaction = transaction; } + + #if NET + /// + protected override DbBatchCommandCollection DbBatchCommands => BatchCommands; + + /// + protected override DbBatchCommand CreateDbBatchCommand() => new SqlBatchCommand(); + #else + /// + public virtual ValueTask DisposeAsync() + { + Dispose(); + return default; + } + #endif + /// - public override int Timeout + public + #if NET + override + #endif + int Timeout { get { @@ -47,12 +70,22 @@ public override int Timeout _batchCommand.CommandTimeout = value; } } - /// - protected override DbBatchCommandCollection DbBatchCommands => BatchCommands; + /// - public new SqlBatchCommandCollection BatchCommands => _providerCommands != null ? _providerCommands : _providerCommands = new SqlBatchCommandCollection(Commands); // Commands call will check disposed + public + #if NET + new + #endif + SqlBatchCommandCollection BatchCommands => _providerCommands != null ? _providerCommands : _providerCommands = new SqlBatchCommandCollection(Commands); // Commands call will check disposed + /// - protected override DbConnection DbConnection + protected + #if NET + override + #else + virtual + #endif + DbConnection DbConnection { get { @@ -65,8 +98,15 @@ protected override DbConnection DbConnection Connection = (SqlConnection)value; } } + /// - protected override DbTransaction DbTransaction + protected + #if NET + override + #else + virtual + #endif + DbTransaction DbTransaction { get { @@ -79,60 +119,103 @@ protected override DbTransaction DbTransaction Transaction = (SqlTransaction)value; } } + /// - public override void Cancel() + public + #if NET + override + #endif + void Cancel() { CheckDisposed(); _batchCommand.Cancel(); } + /// - public override int ExecuteNonQuery() + public + #if NET + override + #endif + int ExecuteNonQuery() { CheckDisposed(); SetupBatchCommandExecute(); return _batchCommand.ExecuteNonQuery(); } + /// - public override Task ExecuteNonQueryAsync(CancellationToken cancellationToken = default) + public + #if NET + override + #endif + Task ExecuteNonQueryAsync(CancellationToken cancellationToken = default) { CheckDisposed(); SetupBatchCommandExecute(); return _batchCommand.ExecuteNonQueryAsync(cancellationToken); } + /// - public override object ExecuteScalar() + public + #if NET + override + #endif + object ExecuteScalar() { CheckDisposed(); SetupBatchCommandExecute(); return _batchCommand.ExecuteScalar(); } + /// - public override Task ExecuteScalarAsync(CancellationToken cancellationToken = default) + public + #if NET + override + #endif + Task ExecuteScalarAsync(CancellationToken cancellationToken = default) { CheckDisposed(); SetupBatchCommandExecute(); return _batchCommand.ExecuteScalarBatchAsync(cancellationToken); } + /// - public override void Prepare() + public + #if NET + override + #endif + void Prepare() { CheckDisposed(); } + /// - public override Task PrepareAsync(CancellationToken cancellationToken = default) + public + #if NET + override + #endif + Task PrepareAsync(CancellationToken cancellationToken = default) { CheckDisposed(); return Task.CompletedTask; } + /// - public override void Dispose() + public + #if NET + override + #endif + void Dispose() { _batchCommand?.Dispose(); _batchCommand = null; _commands?.Clear(); _commands = null; + #if NET base.Dispose(); + #endif } + /// public List Commands { @@ -142,8 +225,13 @@ public List Commands return _commands != null ? _commands : _commands = new List(); } } + /// - public new SqlConnection Connection + public + #if NET + new + #endif + SqlConnection Connection { get { @@ -156,8 +244,13 @@ public List Commands _batchCommand.Connection = value; } } + /// - public new SqlTransaction Transaction + public + #if NET + new + #endif + SqlTransaction Transaction { get { @@ -170,6 +263,7 @@ public List Commands _batchCommand.Transaction = value; } } + /// public SqlDataReader ExecuteReader() { @@ -177,17 +271,36 @@ public SqlDataReader ExecuteReader() SetupBatchCommandExecute(); return _batchCommand.ExecuteReader(); } + /// - public new Task ExecuteReaderAsync(CancellationToken cancellationToken = default) + public + #if NET + new + #endif + Task ExecuteReaderAsync(CancellationToken cancellationToken = default) { CheckDisposed(); SetupBatchCommandExecute(); return _batchCommand.ExecuteReaderAsync(cancellationToken); } + /// - protected override DbDataReader ExecuteDbDataReader(CommandBehavior behavior) => ExecuteReader(); + protected + #if NET + override + #else + virtual + #endif + DbDataReader ExecuteDbDataReader(CommandBehavior behavior) => ExecuteReader(); + /// - protected override Task ExecuteDbDataReaderAsync(CommandBehavior behavior, CancellationToken cancellationToken) + protected + #if NET + override + #else + virtual + #endif + Task ExecuteDbDataReaderAsync(CommandBehavior behavior, CancellationToken cancellationToken) { CheckDisposed(); SetupBatchCommandExecute(); @@ -204,12 +317,8 @@ protected override Task ExecuteDbDataReaderAsync(CommandBehavior b TaskContinuationOptions.ExecuteSynchronously | TaskContinuationOptions.NotOnCanceled, TaskScheduler.Default ); - } - /// - protected override DbBatchCommand CreateDbBatchCommand() - { - return new SqlBatchCommand(); } + private void CheckDisposed() { if (_batchCommand is null) @@ -217,6 +326,7 @@ private void CheckDisposed() throw ADP.ObjectDisposed(this); } } + private void SetupBatchCommandExecute() { SqlConnection connection = Connection; @@ -240,5 +350,3 @@ private void SetupBatchCommandExecute() } } } - -#endif diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlBatchCommand.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlBatchCommand.cs index 3ac8af5a0e..460197a1bc 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlBatchCommand.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlBatchCommand.cs @@ -10,10 +10,10 @@ namespace Microsoft.Data.SqlClient { /// - public partial class SqlBatchCommand -#if NET + public class SqlBatchCommand + #if NET : DbBatchCommand -#endif + #endif { private string _text; private CommandType _type; @@ -68,18 +68,25 @@ internal SqlBatchCommand(string commandText, SqlParameterCollection parameterCol _parameters = parameterCollection; } + /// + public + #if NET + override + #endif + bool CanCreateParameter => true; + /// public -#if NET + #if NET override -#endif + #endif string CommandText { get => _text; set => _text = value; } /// public -#if NET + #if NET override -#endif + #endif CommandType CommandType { get => _type; set => SetCommandType(value); } /// @@ -87,23 +94,25 @@ internal SqlBatchCommand(string commandText, SqlParameterCollection parameterCol /// public -#if NET + #if NET override -#endif + #endif int RecordsAffected { get => _recordsAffected; } /// protected -#if NET - override -#endif + #if NET + override + #else + virtual + #endif DbParameterCollection DbParameterCollection => Parameters; /// public -#if NET + #if NET new -#endif + #endif SqlParameterCollection Parameters { get @@ -123,6 +132,13 @@ internal set /// public SqlCommandColumnEncryptionSetting ColumnEncryptionSetting { get => _encryptionSetting; set => _encryptionSetting = value; } + /// + public + #if NET + override + #endif + DbParameter CreateParameter() => new SqlParameter(); + private void SetCommandType(CommandType value) { if (value != _type) diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlBatchCommand.netcore.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlBatchCommand.netcore.cs deleted file mode 100644 index e55677b96b..0000000000 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlBatchCommand.netcore.cs +++ /dev/null @@ -1,21 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -#if NET - -using System.Data.Common; - -namespace Microsoft.Data.SqlClient -{ - public partial class SqlBatchCommand - { - /// - public override DbParameter CreateParameter() => new SqlParameter(); - - /// - public override bool CanCreateParameter => true; - } -} - -#endif diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlBatchCommandCollection.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlBatchCommandCollection.cs index e4f68aea5d..0546fdfd80 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlBatchCommandCollection.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlBatchCommandCollection.cs @@ -1,15 +1,19 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#if NET +using System.Collections; using System.Collections.Generic; using System.Data.Common; namespace Microsoft.Data.SqlClient { /// - public class SqlBatchCommandCollection : DbBatchCommandCollection, IList + public class SqlBatchCommandCollection : + #if NET + DbBatchCommandCollection, + #endif + IList { readonly List _list; @@ -17,63 +21,107 @@ internal SqlBatchCommandCollection(List batchCommands) { _list = batchCommands; } + /// - public override int Count => _list.Count; + public + #if NET + override + #endif + int Count => _list.Count; + /// - public override bool IsReadOnly => false; - IEnumerator IEnumerable.GetEnumerator() => _list.GetEnumerator(); + public + #if NET + override + #endif + bool IsReadOnly => false; + + /// + public + #if NET + override + #endif + void Clear() => _list.Clear(); + + /// + public + #if NET + override + #endif + void RemoveAt(int index) => _list.RemoveAt(index); + + /// + public + #if NET + new + #endif + SqlBatchCommand this[int index] + { + get => _list[index]; + set => _list[index] = value; + } + + #if NET /// public override IEnumerator GetEnumerator() => _list.GetEnumerator(); - /// - public void Add(SqlBatchCommand item) => _list.Add(item); + /// public override void Add(DbBatchCommand item) => Add((SqlBatchCommand)item); - /// - public override void Clear() => _list.Clear(); - /// - public bool Contains(SqlBatchCommand item) => _list.Contains(item); + /// public override bool Contains(DbBatchCommand item) => Contains((SqlBatchCommand)item); - /// - public void CopyTo(SqlBatchCommand[] array, int arrayIndex) => _list.CopyTo(array, arrayIndex); + /// public override void CopyTo(DbBatchCommand[] array, int arrayIndex) { SqlBatchCommand[] target = (SqlBatchCommand[])array; CopyTo(target, arrayIndex); } - /// - public int IndexOf(SqlBatchCommand item) => _list.IndexOf(item); + /// public override int IndexOf(DbBatchCommand item) => IndexOf((SqlBatchCommand)item); - /// - public void Insert(int index, SqlBatchCommand item) => _list.Insert(index, item); + /// public override void Insert(int index, DbBatchCommand item) => Insert(index, (SqlBatchCommand)item); - /// - public bool Remove(SqlBatchCommand item) => _list.Remove(item); + /// public override bool Remove(DbBatchCommand item) => Remove((SqlBatchCommand)item); - /// - public override void RemoveAt(int index) => _list.RemoveAt(index); + + /// + protected override DbBatchCommand GetBatchCommand(int index) => _list[index]; + + /// + protected override void SetBatchCommand(int index, DbBatchCommand batchCommand) + => _list[index] = (SqlBatchCommand)batchCommand; + #else + IEnumerator IEnumerable.GetEnumerator() => _list.GetEnumerator(); + #endif + + IEnumerator IEnumerable.GetEnumerator() => _list.GetEnumerator(); + + /// + public void Add(SqlBatchCommand item) => _list.Add(item); + + /// + public bool Contains(SqlBatchCommand item) => _list.Contains(item); + + /// + public void CopyTo(SqlBatchCommand[] array, int arrayIndex) => _list.CopyTo(array, arrayIndex); + + /// + public int IndexOf(SqlBatchCommand item) => _list.IndexOf(item); + + /// + public void Insert(int index, SqlBatchCommand item) => _list.Insert(index, item); + + /// + public bool Remove(SqlBatchCommand item) => _list.Remove(item); + /// SqlBatchCommand IList.this[int index] { get => _list[index]; set => _list[index] = value; } - /// - public new SqlBatchCommand this[int index] - { - get => _list[index]; - set => _list[index] = value; - } - /// - protected override DbBatchCommand GetBatchCommand(int index) => _list[index]; - /// - protected override void SetBatchCommand(int index, DbBatchCommand batchCommand) - => _list[index] = (SqlBatchCommand)batchCommand; } } - -#endif diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlCommand.Scalar.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlCommand.Scalar.cs index f44e4476d5..ab50956197 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlCommand.Scalar.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlCommand.Scalar.cs @@ -81,7 +81,6 @@ public override Task ExecuteScalarAsync(CancellationToken cancellationTo return ExecuteScalarAsyncInternal(cancellationToken); } - #if NET internal Task ExecuteScalarBatchAsync(CancellationToken cancellationToken) { Guid operationId = s_diagnosticListener.WriteCommandBefore(this, _transaction); @@ -166,7 +165,6 @@ internal Task ExecuteScalarBatchAsync(CancellationToken cancellationToke }, TaskScheduler.Default).Unwrap(); } - #endif #endregion diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlException.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlException.cs index 1a606242c2..a1735fabe7 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlException.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlException.cs @@ -117,7 +117,7 @@ public override void GetObjectData(SerializationInfo si, StreamingContext contex override public string Source => DbConnectionStringDefaults.ApplicationName; -#if NET + #if NET /// protected override DbBatchCommand DbBatchCommand => BatchCommand; @@ -127,14 +127,15 @@ public override void GetObjectData(SerializationInfo si, StreamingContext contex get => _batchCommand; internal set => _batchCommand = value; } -#else - internal SqlBatchCommand BatchCommand + #else + /// + public SqlBatchCommand BatchCommand { get => _batchCommand; - set => _batchCommand = value; + internal set => _batchCommand = value; } -#endif - + #endif + /// public override string ToString() { diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/Microsoft.Data.SqlClient.ManualTesting.Tests.csproj b/src/Microsoft.Data.SqlClient/tests/ManualTests/Microsoft.Data.SqlClient.ManualTesting.Tests.csproj index 3155b87f81..bd5e9918d9 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/Microsoft.Data.SqlClient.ManualTesting.Tests.csproj +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/Microsoft.Data.SqlClient.ManualTesting.Tests.csproj @@ -170,6 +170,7 @@ + @@ -253,9 +254,6 @@ - - - diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/Batch/BatchTests.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/Batch/BatchTests.cs index a883eb9b88..5322e86093 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/Batch/BatchTests.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/Batch/BatchTests.cs @@ -50,8 +50,12 @@ public static void ConnectionCanCreateBatch() { using (var connection = new SqlConnection(DataTestUtility.TCPConnectionString)) { + #if NET Assert.True(connection.CanCreateBatch); using (var batch = connection.CreateBatch()) + #else + using (var batch = new SqlBatch(connection)) + #endif { Assert.NotNull(batch); Assert.Equal(connection, batch.Connection); @@ -63,13 +67,16 @@ public static void ConnectionCanCreateBatch() } } -#if NET8_0_OR_GREATER [ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup))] public static void SqlBatchCanCreateParameter() { using var connection = new SqlConnection(DataTestUtility.TCPConnectionString); connection.Open(); +#if NET using DbBatch batch = connection.CreateBatch(); +#else + using SqlBatch batch = new SqlBatch(connection); +#endif SqlBatchCommand batchCommand = new SqlBatchCommand("SELECT @p"); Assert.True(batchCommand.CanCreateParameter); @@ -81,7 +88,6 @@ public static void SqlBatchCanCreateParameter() batch.BatchCommands.Add(batchCommand); batch.ExecuteNonQuery(); } -#endif [ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup))] public static void StoredProcedureBatchSupported() @@ -154,7 +160,11 @@ public static void ProviderApi() int resultCount = 0; int rowCount = 0; var dbProviderFactory = SqlClientFactory.Instance; + #if NET DbBatch batch = dbProviderFactory.CreateBatch(); + #else + SqlBatch batch = new SqlBatch(); + #endif using (var connection = new SqlConnection(DataTestUtility.TCPConnectionString)) { connection.Open(); @@ -167,7 +177,11 @@ public static void ProviderApi() p2.ParameterName = "@p2"; p1.Value = 50.0f; p2.Value = 10248; + #if NET DbBatchCommand command = dbProviderFactory.CreateBatchCommand(); + #else + SqlBatchCommand command = new SqlBatchCommand(); + #endif command.CommandText = "UPDATE Orders SET Freight=@p1 WHERE OrderID=@p2"; command.Parameters.Add(p1); command.Parameters.Add(p2); @@ -178,7 +192,11 @@ public static void ProviderApi() DbParameter parameter = dbProviderFactory.CreateParameter(); parameter.ParameterName = "@p4"; parameter.Value = 10248; + #if NET DbBatchCommand command = dbProviderFactory.CreateBatchCommand(); + #else + SqlBatchCommand command = new SqlBatchCommand(); + #endif command.CommandText = $"SELECT Freight FROM Orders WHERE OrderID={parameter.ParameterName}"; command.Parameters.Add(parameter); batch.BatchCommands.Add(command); From c97125eca6e17fbaf40f75994c7c7d2bca3e2200 Mon Sep 17 00:00:00 2001 From: Edward Neal <55035479+edwardneal@users.noreply.github.com> Date: Wed, 15 Apr 2026 21:55:53 +0100 Subject: [PATCH 2/4] Post-merge reconciliation --- .../ref/Microsoft.Data.SqlClient.cs | 161 ++++++++++++++++-- ...icrosoft.Data.SqlClient.ManualTests.csproj | 2 +- .../{BatchTests.netcore.cs => BatchTests.cs} | 6 +- 3 files changed, 153 insertions(+), 16 deletions(-) rename src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/Batch/{BatchTests.netcore.cs => BatchTests.cs} (99%) diff --git a/src/Microsoft.Data.SqlClient/ref/Microsoft.Data.SqlClient.cs b/src/Microsoft.Data.SqlClient/ref/Microsoft.Data.SqlClient.cs index ce6e481434..a242d6f50f 100644 --- a/src/Microsoft.Data.SqlClient/ref/Microsoft.Data.SqlClient.cs +++ b/src/Microsoft.Data.SqlClient/ref/Microsoft.Data.SqlClient.cs @@ -47,137 +47,275 @@ protected SqlAuthenticationInitializer() { } public abstract void Initialize(); } -#if NET /// +#if NET public class SqlBatch : System.Data.Common.DbBatch +#else +public class SqlBatch : System.IDisposable, System.IAsyncDisposable +#endif { /// public SqlBatch() { throw null; } /// public SqlBatch(Microsoft.Data.SqlClient.SqlConnection connection, Microsoft.Data.SqlClient.SqlTransaction transaction = null) { throw null; } /// + #if NET public override int Timeout { get => throw null; set { } } + #else + public int Timeout { get => throw null; set { } } + #endif /// public System.Collections.Generic.List Commands { get { throw null; } } /// + #if NET public new Microsoft.Data.SqlClient.SqlConnection Connection { get => throw null; set { } } + #else + public Microsoft.Data.SqlClient.SqlConnection Connection { get => throw null; set { } } + #endif /// + #if NET public new Microsoft.Data.SqlClient.SqlTransaction Transaction { get => throw null; set { } } + #else + public Microsoft.Data.SqlClient.SqlTransaction Transaction { get => throw null; set { } } + #endif /// + #if NET public new SqlBatchCommandCollection BatchCommands { get => throw null; } + #else + public SqlBatchCommandCollection BatchCommands { get => throw null; } + #endif + #if NET /// protected override System.Data.Common.DbBatchCommandCollection DbBatchCommands { get => throw null; } + #endif /// + #if NET protected override System.Data.Common.DbConnection DbConnection { get => throw null; set { } } + #else + protected virtual System.Data.Common.DbConnection DbConnection { get => throw null; set { } } + #endif /// + #if NET protected override System.Data.Common.DbTransaction DbTransaction { get => throw null; set { } } + #else + protected virtual System.Data.Common.DbTransaction DbTransaction { get => throw null; set { } } + #endif /// + #if NET public override void Cancel() => throw null; - /// + #else + public void Cancel() => throw null; + #endif + #if NET + /// protected override System.Data.Common.DbBatchCommand CreateDbBatchCommand() => throw null; + #endif /// + #if NET public override void Dispose() => throw null; + #else + public void Dispose() => throw null; + #endif + #if !NET + /// + public virtual System.Threading.Tasks.ValueTask DisposeAsync() => throw null; + #endif /// + #if NET protected override System.Data.Common.DbDataReader ExecuteDbDataReader(System.Data.CommandBehavior behavior) => throw null; + #else + protected virtual System.Data.Common.DbDataReader ExecuteDbDataReader(System.Data.CommandBehavior behavior) => throw null; + #endif /// + #if NET protected override System.Threading.Tasks.Task ExecuteDbDataReaderAsync(System.Data.CommandBehavior behavior, System.Threading.CancellationToken cancellationToken) => throw null; + #else + protected virtual System.Threading.Tasks.Task ExecuteDbDataReaderAsync(System.Data.CommandBehavior behavior, System.Threading.CancellationToken cancellationToken) => throw null; + #endif /// + #if NET public override int ExecuteNonQuery() => throw null; + #else + public int ExecuteNonQuery() => throw null; + #endif /// + #if NET public override System.Threading.Tasks.Task ExecuteNonQueryAsync(System.Threading.CancellationToken cancellationToken = default) => throw null; + #else + public System.Threading.Tasks.Task ExecuteNonQueryAsync(System.Threading.CancellationToken cancellationToken = default) => throw null; + #endif /// public Microsoft.Data.SqlClient.SqlDataReader ExecuteReader() => throw null; /// + #if NET public new System.Threading.Tasks.Task ExecuteReaderAsync(System.Threading.CancellationToken cancellationToken = default) => throw null; + #else + public System.Threading.Tasks.Task ExecuteReaderAsync(System.Threading.CancellationToken cancellationToken = default) => throw null; + #endif /// + #if NET public override object ExecuteScalar() => throw null; + #else + public object ExecuteScalar() => throw null; + #endif /// + #if NET public override System.Threading.Tasks.Task ExecuteScalarAsync(System.Threading.CancellationToken cancellationToken = default) => throw null; + #else + public System.Threading.Tasks.Task ExecuteScalarAsync(System.Threading.CancellationToken cancellationToken = default) => throw null; + #endif /// + #if NET public override void Prepare() => throw null; + #else + public void Prepare() => throw null; + #endif /// + #if NET public override System.Threading.Tasks.Task PrepareAsync(System.Threading.CancellationToken cancellationToken = default) => throw null; + #else + public System.Threading.Tasks.Task PrepareAsync(System.Threading.CancellationToken cancellationToken = default) => throw null; + #endif } -#endif -#if NET /// -public partial class SqlBatchCommand : System.Data.Common.DbBatchCommand +#if NET +public class SqlBatchCommand : System.Data.Common.DbBatchCommand +#else +public class SqlBatchCommand +#endif { /// public SqlBatchCommand() => throw null; /// public SqlBatchCommand(string commandText, System.Data.CommandType commandType = System.Data.CommandType.Text, System.Collections.Generic.IEnumerable parameters = null, Microsoft.Data.SqlClient.SqlCommandColumnEncryptionSetting columnEncryptionSetting = Microsoft.Data.SqlClient.SqlCommandColumnEncryptionSetting.UseConnectionSetting) { throw null; } /// + #if NET public new Microsoft.Data.SqlClient.SqlParameterCollection Parameters { get { throw null; } } + #else + public Microsoft.Data.SqlClient.SqlParameterCollection Parameters { get { throw null; } } + #endif /// + #if NET public override string CommandText { get { throw null; } set { } } + #else + public string CommandText { get { throw null; } set { } } + #endif /// + #if NET public override System.Data.CommandType CommandType { get { throw null; } set { } } + #else + public System.Data.CommandType CommandType { get { throw null; } set { } } + #endif /// public System.Data.CommandBehavior CommandBehavior { get { throw null; } set { } } /// + #if NET public override int RecordsAffected { get { throw null; } } + #else + public int RecordsAffected { get { throw null; } } + #endif /// + #if NET protected override System.Data.Common.DbParameterCollection DbParameterCollection => throw null; + #else + protected virtual System.Data.Common.DbParameterCollection DbParameterCollection => throw null; + #endif - #if NET /// public Microsoft.Data.SqlClient.SqlCommandColumnEncryptionSetting ColumnEncryptionSetting { get { throw null; } set { } } - #endif } -#endif -#if NET /// +#if NET public class SqlBatchCommandCollection : System.Data.Common.DbBatchCommandCollection, System.Collections.Generic.IList +#else +public class SqlBatchCommandCollection : System.Collections.Generic.IList +#endif { /// + #if NET public override int Count => throw null; + #else + public int Count => throw null; + #endif /// + #if NET public override bool IsReadOnly => throw null; + #else + public bool IsReadOnly => throw null; + #endif System.Collections.Generic.IEnumerator System.Collections.Generic.IEnumerable.GetEnumerator() => throw null; + #if NET /// public override System.Collections.Generic.IEnumerator GetEnumerator() => throw null; + #endif /// public void Add(Microsoft.Data.SqlClient.SqlBatchCommand item) => throw null; + #if NET /// public override void Add(System.Data.Common.DbBatchCommand item) => throw null; + #endif /// + #if NET public override void Clear() => throw null; + #else + public void Clear() => throw null; + #endif /// public bool Contains(Microsoft.Data.SqlClient.SqlBatchCommand item) => throw null; + #if NET /// public override bool Contains(System.Data.Common.DbBatchCommand item) => throw null; + #endif /// public void CopyTo(Microsoft.Data.SqlClient.SqlBatchCommand[] array, int arrayIndex) => throw null; + #if NET /// public override void CopyTo(System.Data.Common.DbBatchCommand[] array, int arrayIndex) => throw null; + #endif /// public int IndexOf(Microsoft.Data.SqlClient.SqlBatchCommand item) => throw null; + #if NET /// public override int IndexOf(System.Data.Common.DbBatchCommand item) => throw null; + #endif /// public void Insert(int index, Microsoft.Data.SqlClient.SqlBatchCommand item) => throw null; + #if NET /// public override void Insert(int index, System.Data.Common.DbBatchCommand item) => throw null; + #endif /// public bool Remove(Microsoft.Data.SqlClient.SqlBatchCommand item) => throw null; + #if NET /// public override bool Remove(System.Data.Common.DbBatchCommand item) => throw null; + #endif /// + #if NET public override void RemoveAt(int index) => throw null; + #else + public void RemoveAt(int index) => throw null; + #endif /// Microsoft.Data.SqlClient.SqlBatchCommand System.Collections.Generic.IList.this[int index] { get => throw null; set { } } /// + #if NET public new Microsoft.Data.SqlClient.SqlBatchCommand this[int index] { get => throw null; set { } } + #else + public Microsoft.Data.SqlClient.SqlBatchCommand this[int index] { get => throw null; set { } } + #endif System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => throw null; + #if NET /// protected override System.Data.Common.DbBatchCommand GetBatchCommand(int index) => throw null; + #endif + #if NET /// protected override void SetBatchCommand(int index, System.Data.Common.DbBatchCommand batchCommand) => throw null; + #endif } -#endif /// public sealed class SqlBulkCopy : System.IDisposable @@ -1653,6 +1791,9 @@ private SqlException(System.Runtime.Serialization.SerializationInfo info, System #if NET /// public new Microsoft.Data.SqlClient.SqlBatchCommand BatchCommand { get { throw null; } } + #else + /// + public Microsoft.Data.SqlClient.SqlBatchCommand BatchCommand { get { throw null; } } #endif /// diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/Microsoft.Data.SqlClient.ManualTests.csproj b/src/Microsoft.Data.SqlClient/tests/ManualTests/Microsoft.Data.SqlClient.ManualTests.csproj index c28f1cfeb7..110547a5de 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/Microsoft.Data.SqlClient.ManualTests.csproj +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/Microsoft.Data.SqlClient.ManualTests.csproj @@ -191,7 +191,7 @@ - + diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/Batch/BatchTests.netcore.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/Batch/BatchTests.cs similarity index 99% rename from src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/Batch/BatchTests.netcore.cs rename to src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/Batch/BatchTests.cs index 4ce28591d7..991d55cdeb 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/Batch/BatchTests.netcore.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/Batch/BatchTests.cs @@ -1,9 +1,7 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -#if NET - using System; using System.Collections.Generic; using System.Data; @@ -683,5 +681,3 @@ private static bool TryExecuteNonQueryCommand(string command) } } } - -#endif From b848195d497a2931c93b29a53d69fe618430490d Mon Sep 17 00:00:00 2001 From: Edward Neal <55035479+edwardneal@users.noreply.github.com> Date: Wed, 15 Apr 2026 22:43:38 +0100 Subject: [PATCH 3/4] Add missing members to ref assembly --- .../ref/Microsoft.Data.SqlClient.cs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/Microsoft.Data.SqlClient/ref/Microsoft.Data.SqlClient.cs b/src/Microsoft.Data.SqlClient/ref/Microsoft.Data.SqlClient.cs index a242d6f50f..de581dbb0e 100644 --- a/src/Microsoft.Data.SqlClient/ref/Microsoft.Data.SqlClient.cs +++ b/src/Microsoft.Data.SqlClient/ref/Microsoft.Data.SqlClient.cs @@ -195,6 +195,12 @@ public class SqlBatchCommand #else public Microsoft.Data.SqlClient.SqlParameterCollection Parameters { get { throw null; } } #endif + /// + #if NET + public override bool CanCreateParameter { get { throw null; } } + #else + public bool CanCreateParameter { get { throw null; } set { } } + #endif /// #if NET public override string CommandText { get { throw null; } set { } } @@ -209,6 +215,12 @@ public class SqlBatchCommand #endif /// public System.Data.CommandBehavior CommandBehavior { get { throw null; } set { } } + /// + #if NET + public override System.Data.Common.DbParameter CreateParameter() => throw null; + #else + public System.Data.Common.DbParameter CreateParameter() => throw null; + #endif /// #if NET public override int RecordsAffected { get { throw null; } } From 7e416bd9ab157e7ab3e3175346f105d955d702df Mon Sep 17 00:00:00 2001 From: Edward Neal <55035479+edwardneal@users.noreply.github.com> Date: Fri, 17 Apr 2026 06:11:31 +0100 Subject: [PATCH 4/4] Split conditional compilation blocks --- .../src/Microsoft/Data/SqlClient/SqlBatch.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlBatch.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlBatch.cs index 30ca4a73dc..a1f79f6f15 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlBatch.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlBatch.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -43,7 +43,9 @@ public SqlBatch(SqlConnection connection = null, SqlTransaction transaction = nu /// protected override DbBatchCommand CreateDbBatchCommand() => new SqlBatchCommand(); - #else + #endif + + #if NETFRAMEWORK /// public virtual ValueTask DisposeAsync() {