1
1
using System ;
2
2
using System . Data ;
3
+ using System . Data . Common ;
3
4
using System . Diagnostics . CodeAnalysis ;
4
5
using System . Threading ;
5
6
using System . Threading . Tasks ;
@@ -53,7 +54,11 @@ namespace MySqlConnector
53
54
/// </code>
54
55
/// </summary>
55
56
/// <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
57
62
{
58
63
/// <summary>
59
64
/// 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
76
81
m_commandId = ICancellableCommandExtensions . GetNextId ( ) ;
77
82
}
78
83
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
79
90
public MySqlConnection ? Connection { get ; set ; }
80
91
public MySqlTransaction ? Transaction { get ; set ; }
92
+ #endif
81
93
82
94
/// <summary>
83
95
/// The collection of commands that will be executed in the batch.
84
96
/// </summary>
97
+ #if NET6_0_OR_GREATER
98
+ public new MySqlBatchCommandCollection BatchCommands { get ; }
99
+ protected override DbBatchCommandCollection DbBatchCommands => BatchCommands ;
100
+ #else
85
101
public MySqlBatchCommandCollection BatchCommands { get ; }
102
+ #endif
86
103
87
104
/// <summary>
88
105
/// Executes all the commands in the batch, returning a <see cref="MySqlDataReader"/> that can iterate
89
106
/// over the result sets. If multiple resultsets are returned, use <see cref="MySqlDataReader.NextResult"/>
90
107
/// to access them.
91
108
/// </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 ) ;
93
115
94
116
/// <summary>
95
117
/// 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
98
120
/// </summary>
99
121
/// <param name="cancellationToken">A token to cancel the asynchronous operation.</param>
100
122
/// <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
104
137
{
105
138
( ( ICancellableCommand ) this ) . ResetCommandTimeout ( ) ;
106
139
return ExecuteReaderAsync ( IOBehavior . Synchronous , CancellationToken . None ) . GetAwaiter ( ) . GetResult ( ) ;
107
140
}
108
141
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
110
147
{
111
148
( ( ICancellableCommand ) this ) . ResetCommandTimeout ( ) ;
112
149
using var registration = ( ( ICancellableCommand ) this ) . RegisterCancel ( cancellationToken ) ;
@@ -118,26 +155,54 @@ private Task<MySqlDataReader> ExecuteReaderAsync(IOBehavior ioBehavior, Cancella
118
155
if ( ! IsValid ( out var exception ) )
119
156
return Utility . TaskFromException < MySqlDataReader > ( exception ) ;
120
157
121
- foreach ( var batchCommand in BatchCommands )
158
+ foreach ( MySqlBatchCommand batchCommand in BatchCommands )
122
159
batchCommand . Batch = this ;
123
160
124
161
var payloadCreator = Connection ! . Session . SupportsComMulti ? BatchedCommandPayloadCreator . Instance :
125
162
IsPrepared ? SingleCommandPayloadCreator . Instance :
126
163
ConcatenatedCommandPayloadCreator . Instance ;
127
- return CommandExecutor . ExecuteReaderAsync ( BatchCommands ! , payloadCreator , CommandBehavior . Default , ioBehavior , cancellationToken ) ;
164
+ return CommandExecutor . ExecuteReaderAsync ( BatchCommands ! . Commands , payloadCreator , CommandBehavior . Default , ioBehavior , cancellationToken ) ;
128
165
}
129
166
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
138
198
public int Timeout { get ; set ; }
199
+ #endif
139
200
201
+ #if NET6_0_OR_GREATER
202
+ public override void Prepare ( )
203
+ #else
140
204
public void Prepare ( )
205
+ #endif
141
206
{
142
207
if ( ! NeedsPrepare ( out var exception ) )
143
208
{
@@ -149,11 +214,29 @@ public void Prepare()
149
214
DoPrepareAsync ( IOBehavior . Synchronous , default ) . GetAwaiter ( ) . GetResult ( ) ;
150
215
}
151
216
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
156
238
public void Dispose ( )
239
+ #endif
157
240
{
158
241
m_isDisposed = true ;
159
242
}
@@ -207,7 +290,7 @@ private async Task<int> ExecuteNonQueryAsync(IOBehavior ioBehavior, Cancellation
207
290
return reader . RecordsAffected ;
208
291
}
209
292
210
- private async Task < object > ExecuteScalarAsync ( IOBehavior ioBehavior , CancellationToken cancellationToken )
293
+ private async Task < object ? > ExecuteScalarAsync ( IOBehavior ioBehavior , CancellationToken cancellationToken )
211
294
{
212
295
( ( ICancellableCommand ) this ) . ResetCommandTimeout ( ) ;
213
296
using var registration = ( ( ICancellableCommand ) this ) . RegisterCancel ( cancellationToken ) ;
@@ -224,7 +307,7 @@ private async Task<object> ExecuteScalarAsync(IOBehavior ioBehavior, Cancellatio
224
307
hasSetResult = true ;
225
308
}
226
309
} while ( await reader . NextResultAsync ( ioBehavior , cancellationToken ) . ConfigureAwait ( false ) ) ;
227
- return result ! ;
310
+ return result ;
228
311
}
229
312
230
313
private bool IsValid ( [ NotNullWhen ( false ) ] out Exception ? exception )
@@ -248,7 +331,6 @@ private bool IsValid([NotNullWhen(false)] out Exception? exception)
248
331
249
332
private bool NeedsPrepare ( out Exception ? exception )
250
333
{
251
- exception = null ;
252
334
if ( m_isDisposed )
253
335
exception = new ObjectDisposedException ( GetType ( ) . Name ) ;
254
336
else if ( Connection is null )
@@ -271,8 +353,6 @@ private bool NeedsPrepare(out Exception? exception)
271
353
{
272
354
if ( command is null )
273
355
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" ) ;
276
356
if ( string . IsNullOrWhiteSpace ( command . CommandText ) )
277
357
return new InvalidOperationException ( "CommandText must be specified on each batch command" ) ;
278
358
}
0 commit comments