11using System ;
22using System . Data ;
3+ using System . Data . Common ;
34using System . Diagnostics . CodeAnalysis ;
45using System . Threading ;
56using System . Threading . Tasks ;
@@ -53,7 +54,11 @@ namespace MySqlConnector
5354 /// </code>
5455 /// </summary>
5556 /// <remarks>The proposed ADO.NET API that <see cref="MySqlBatch"/> is based on is not finalized. This API is experimental and may change in the future.</remarks>
56- public sealed class MySqlBatch : ICancellableCommand , IDisposable
57+ public sealed class MySqlBatch :
58+ #if NET6_0_OR_GREATER
59+ DbBatch ,
60+ #endif
61+ ICancellableCommand , IDisposable
5762 {
5863 /// <summary>
5964 /// Initializes a new <see cref="MySqlBatch"/> object. The <see cref="Connection"/> property must be set before this object can be used.
@@ -76,20 +81,37 @@ public MySqlBatch(MySqlConnection? connection = null, MySqlTransaction? transact
7681 m_commandId = ICancellableCommandExtensions . GetNextId ( ) ;
7782 }
7883
84+ #if NET6_0_OR_GREATER
85+ public new MySqlConnection ? Connection { get ; set ; }
86+ protected override DbConnection ? DbConnection { get => Connection ; set => Connection = ( MySqlConnection ? ) value ; }
87+ public new MySqlTransaction ? Transaction { get ; set ; }
88+ protected override DbTransaction ? DbTransaction { get => Transaction ; set => Transaction = ( MySqlTransaction ? ) value ; }
89+ #else
7990 public MySqlConnection ? Connection { get ; set ; }
8091 public MySqlTransaction ? Transaction { get ; set ; }
92+ #endif
8193
8294 /// <summary>
8395 /// The collection of commands that will be executed in the batch.
8496 /// </summary>
97+ #if NET6_0_OR_GREATER
98+ public new MySqlBatchCommandCollection BatchCommands { get ; }
99+ protected override DbBatchCommandCollection DbBatchCommands => BatchCommands ;
100+ #else
85101 public MySqlBatchCommandCollection BatchCommands { get ; }
102+ #endif
86103
87104 /// <summary>
88105 /// Executes all the commands in the batch, returning a <see cref="MySqlDataReader"/> that can iterate
89106 /// over the result sets. If multiple resultsets are returned, use <see cref="MySqlDataReader.NextResult"/>
90107 /// to access them.
91108 /// </summary>
92- public MySqlDataReader ExecuteReader ( ) => ExecuteDbDataReader ( ) ;
109+ #if NET6_0_OR_GREATER
110+ public new MySqlDataReader ExecuteReader ( CommandBehavior commandBehavior = CommandBehavior . Default ) =>
111+ #else
112+ public MySqlDataReader ExecuteReader ( CommandBehavior commandBehavior = CommandBehavior . Default ) =>
113+ #endif
114+ ( MySqlDataReader ) ExecuteDbDataReader ( commandBehavior ) ;
93115
94116 /// <summary>
95117 /// Executes all the commands in the batch, returning a <see cref="MySqlDataReader"/> that can iterate
@@ -98,15 +120,30 @@ public MySqlBatch(MySqlConnection? connection = null, MySqlTransaction? transact
98120 /// </summary>
99121 /// <param name="cancellationToken">A token to cancel the asynchronous operation.</param>
100122 /// <returns>A <see cref="Task{MySqlDataReader}"/> containing the result of the asynchronous operation.</returns>
101- public Task < MySqlDataReader > ExecuteReaderAsync ( CancellationToken cancellationToken = default ) => ExecuteDbDataReaderAsync ( cancellationToken ) ;
102-
103- private MySqlDataReader ExecuteDbDataReader ( )
123+ #if NET6_0_OR_GREATER
124+ public new async Task < MySqlDataReader > ExecuteReaderAsync ( CancellationToken cancellationToken = default ) =>
125+ #else
126+ public async Task < MySqlDataReader > ExecuteReaderAsync ( CancellationToken cancellationToken = default ) =>
127+ #endif
128+ ( MySqlDataReader ) await ExecuteDbDataReaderAsync ( CommandBehavior . Default , cancellationToken ) ;
129+
130+ // TODO: new ExecuteReaderAsync(CommandBehavior)
131+
132+ #if NET6_0_OR_GREATER
133+ protected override DbDataReader ExecuteDbDataReader ( CommandBehavior behavior )
134+ #else
135+ private DbDataReader ExecuteDbDataReader ( CommandBehavior behavior )
136+ #endif
104137 {
105138 ( ( ICancellableCommand ) this ) . ResetCommandTimeout ( ) ;
106139 return ExecuteReaderAsync ( IOBehavior . Synchronous , CancellationToken . None ) . GetAwaiter ( ) . GetResult ( ) ;
107140 }
108141
109- private async Task < MySqlDataReader > ExecuteDbDataReaderAsync ( CancellationToken cancellationToken )
142+ #if NET6_0_OR_GREATER
143+ protected override async Task < DbDataReader > ExecuteDbDataReaderAsync ( CommandBehavior behavior , CancellationToken cancellationToken )
144+ #else
145+ private async Task < DbDataReader > ExecuteDbDataReaderAsync ( CommandBehavior behavior , CancellationToken cancellationToken )
146+ #endif
110147 {
111148 ( ( ICancellableCommand ) this ) . ResetCommandTimeout ( ) ;
112149 using var registration = ( ( ICancellableCommand ) this ) . RegisterCancel ( cancellationToken ) ;
@@ -118,26 +155,54 @@ private Task<MySqlDataReader> ExecuteReaderAsync(IOBehavior ioBehavior, Cancella
118155 if ( ! IsValid ( out var exception ) )
119156 return Utility . TaskFromException < MySqlDataReader > ( exception ) ;
120157
121- foreach ( var batchCommand in BatchCommands )
158+ foreach ( MySqlBatchCommand batchCommand in BatchCommands )
122159 batchCommand . Batch = this ;
123160
124161 var payloadCreator = Connection ! . Session . SupportsComMulti ? BatchedCommandPayloadCreator . Instance :
125162 IsPrepared ? SingleCommandPayloadCreator . Instance :
126163 ConcatenatedCommandPayloadCreator . Instance ;
127- return CommandExecutor . ExecuteReaderAsync ( BatchCommands ! , payloadCreator , CommandBehavior . Default , ioBehavior , cancellationToken ) ;
164+ return CommandExecutor . ExecuteReaderAsync ( BatchCommands ! . Commands , payloadCreator , CommandBehavior . Default , ioBehavior , cancellationToken ) ;
128165 }
129166
130- public int ExecuteNonQuery ( ) => ExecuteNonQueryAsync ( IOBehavior . Synchronous , CancellationToken . None ) . GetAwaiter ( ) . GetResult ( ) ;
131-
132- public object ExecuteScalar ( ) => ExecuteScalarAsync ( IOBehavior . Synchronous , CancellationToken . None ) . GetAwaiter ( ) . GetResult ( ) ;
133-
134- public Task < int > ExecuteNonQueryAsync ( CancellationToken cancellationToken = default ) => ExecuteNonQueryAsync ( AsyncIOBehavior , cancellationToken ) ;
135-
136- public Task < object > ExecuteScalarAsync ( CancellationToken cancellationToken = default ) => ExecuteScalarAsync ( AsyncIOBehavior , cancellationToken ) ;
137-
167+ #if NET6_0_OR_GREATER
168+ public override int ExecuteNonQuery ( ) =>
169+ #else
170+ public int ExecuteNonQuery ( ) =>
171+ #endif
172+ ExecuteNonQueryAsync ( IOBehavior . Synchronous , CancellationToken . None ) . GetAwaiter ( ) . GetResult ( ) ;
173+
174+ #if NET6_0_OR_GREATER
175+ public override object ? ExecuteScalar ( ) =>
176+ #else
177+ public object ? ExecuteScalar ( ) =>
178+ #endif
179+ ExecuteScalarAsync ( IOBehavior . Synchronous , CancellationToken . None ) . GetAwaiter ( ) . GetResult ( ) ;
180+
181+ #if NET6_0_OR_GREATER
182+ public override Task < int > ExecuteNonQueryAsync ( CancellationToken cancellationToken = default ) =>
183+ #else
184+ public Task < int > ExecuteNonQueryAsync ( CancellationToken cancellationToken = default ) =>
185+ #endif
186+ ExecuteNonQueryAsync ( AsyncIOBehavior , cancellationToken ) ;
187+
188+ #if NET6_0_OR_GREATER
189+ public override Task < object ? > ExecuteScalarAsync ( CancellationToken cancellationToken = default ) =>
190+ #else
191+ public Task < object ? > ExecuteScalarAsync ( CancellationToken cancellationToken = default ) =>
192+ #endif
193+ ExecuteScalarAsync ( AsyncIOBehavior , cancellationToken ) ;
194+
195+ #if NET6_0_OR_GREATER
196+ public override int Timeout { get ; set ; }
197+ #else
138198 public int Timeout { get ; set ; }
199+ #endif
139200
201+ #if NET6_0_OR_GREATER
202+ public override void Prepare ( )
203+ #else
140204 public void Prepare ( )
205+ #endif
141206 {
142207 if ( ! NeedsPrepare ( out var exception ) )
143208 {
@@ -149,11 +214,29 @@ public void Prepare()
149214 DoPrepareAsync ( IOBehavior . Synchronous , default ) . GetAwaiter ( ) . GetResult ( ) ;
150215 }
151216
152- public Task PrepareAsync ( CancellationToken cancellationToken = default ) => PrepareAsync ( AsyncIOBehavior , cancellationToken ) ;
153-
154- public void Cancel ( ) => Connection ? . Cancel ( this , m_commandId , true ) ;
155-
217+ #if NET6_0_OR_GREATER
218+ public override Task PrepareAsync ( CancellationToken cancellationToken = default ) =>
219+ #else
220+ public Task PrepareAsync ( CancellationToken cancellationToken = default ) =>
221+ #endif
222+ PrepareAsync ( AsyncIOBehavior , cancellationToken ) ;
223+
224+ #if NET6_0_OR_GREATER
225+ public override void Cancel ( ) =>
226+ #else
227+ public void Cancel ( ) =>
228+ #endif
229+ Connection ? . Cancel ( this , m_commandId , true ) ;
230+
231+ #if NET6_0_OR_GREATER
232+ protected override DbBatchCommand CreateDbBatchCommand ( ) => new MySqlBatchCommand ( ) ;
233+ #endif
234+
235+ #if NET6_0_OR_GREATER
236+ public override void Dispose ( )
237+ #else
156238 public void Dispose ( )
239+ #endif
157240 {
158241 m_isDisposed = true ;
159242 }
@@ -207,7 +290,7 @@ private async Task<int> ExecuteNonQueryAsync(IOBehavior ioBehavior, Cancellation
207290 return reader . RecordsAffected ;
208291 }
209292
210- private async Task < object > ExecuteScalarAsync ( IOBehavior ioBehavior , CancellationToken cancellationToken )
293+ private async Task < object ? > ExecuteScalarAsync ( IOBehavior ioBehavior , CancellationToken cancellationToken )
211294 {
212295 ( ( ICancellableCommand ) this ) . ResetCommandTimeout ( ) ;
213296 using var registration = ( ( ICancellableCommand ) this ) . RegisterCancel ( cancellationToken ) ;
@@ -224,7 +307,7 @@ private async Task<object> ExecuteScalarAsync(IOBehavior ioBehavior, Cancellatio
224307 hasSetResult = true ;
225308 }
226309 } while ( await reader . NextResultAsync ( ioBehavior , cancellationToken ) . ConfigureAwait ( false ) ) ;
227- return result ! ;
310+ return result ;
228311 }
229312
230313 private bool IsValid ( [ NotNullWhen ( false ) ] out Exception ? exception )
@@ -248,7 +331,6 @@ private bool IsValid([NotNullWhen(false)] out Exception? exception)
248331
249332 private bool NeedsPrepare ( out Exception ? exception )
250333 {
251- exception = null ;
252334 if ( m_isDisposed )
253335 exception = new ObjectDisposedException ( GetType ( ) . Name ) ;
254336 else if ( Connection is null )
@@ -271,8 +353,6 @@ private bool NeedsPrepare(out Exception? exception)
271353 {
272354 if ( command is null )
273355 return new InvalidOperationException ( "BatchCommands must not contain null" ) ;
274- if ( ( command . CommandBehavior & CommandBehavior . CloseConnection ) != 0 )
275- return new NotSupportedException ( "CommandBehavior.CloseConnection is not supported by MySqlBatch" ) ;
276356 if ( string . IsNullOrWhiteSpace ( command . CommandText ) )
277357 return new InvalidOperationException ( "CommandText must be specified on each batch command" ) ;
278358 }
0 commit comments