@@ -24,11 +24,10 @@ public static class EFExtensions
24
24
/// <param name="prependDefaultSchema">Prepend the default schema name to <paramref name="storedProcName"/> if explicitly defined in <paramref name="context"/></param>
25
25
/// <param name="commandTimeout">Command timeout in seconds. Default is 30.</param>
26
26
/// <returns></returns>
27
- public static DbCommand LoadStoredProc ( this DbContext context , string storedProcName , bool prependDefaultSchema = true , short commandTimeout = 30 )
27
+ public static DbCommand LoadStoredProc ( this DbContext context , string storedProcName ,
28
+ bool prependDefaultSchema = true , short commandTimeout = 30 )
28
29
{
29
-
30
30
var cmd = context . Database . GetDbConnection ( ) . CreateCommand ( ) ;
31
-
32
31
cmd . CommandTimeout = commandTimeout ;
33
32
34
33
if ( prependDefaultSchema )
@@ -56,15 +55,17 @@ public static DbCommand LoadStoredProc(this DbContext context, string storedProc
56
55
/// <param name="cmd"></param>
57
56
/// <param name="paramName"></param>
58
57
/// <param name="paramValue"></param>
58
+ /// <param name="configureParam"></param>
59
59
/// <returns></returns>
60
- public static DbCommand WithSqlParam ( this DbCommand cmd , string paramName , object paramValue , Action < DbParameter > configureParam = null )
60
+ public static DbCommand WithSqlParam ( this DbCommand cmd , string paramName , object paramValue ,
61
+ Action < DbParameter > configureParam = null )
61
62
{
62
63
if ( string . IsNullOrEmpty ( cmd . CommandText ) && cmd . CommandType != System . Data . CommandType . StoredProcedure )
63
64
throw new InvalidOperationException ( "Call LoadStoredProc before using this method" ) ;
64
65
65
66
var param = cmd . CreateParameter ( ) ;
66
67
param . ParameterName = paramName ;
67
- param . Value = ( paramValue != null ? paramValue : DBNull . Value ) ;
68
+ param . Value = paramValue ?? DBNull . Value ;
68
69
configureParam ? . Invoke ( param ) ;
69
70
cmd . Parameters . Add ( param ) ;
70
71
return cmd ;
@@ -75,9 +76,10 @@ public static DbCommand WithSqlParam(this DbCommand cmd, string paramName, objec
75
76
/// </summary>
76
77
/// <param name="cmd"></param>
77
78
/// <param name="paramName"></param>
78
- /// <param name="paramValue "></param>
79
+ /// <param name="configureParam "></param>
79
80
/// <returns></returns>
80
- public static DbCommand WithSqlParam ( this DbCommand cmd , string paramName , Action < DbParameter > configureParam = null )
81
+ public static DbCommand WithSqlParam ( this DbCommand cmd , string paramName ,
82
+ Action < DbParameter > configureParam = null )
81
83
{
82
84
if ( string . IsNullOrEmpty ( cmd . CommandText ) && cmd . CommandType != System . Data . CommandType . StoredProcedure )
83
85
throw new InvalidOperationException ( "Call LoadStoredProc before using this method" ) ;
@@ -90,14 +92,13 @@ public static DbCommand WithSqlParam(this DbCommand cmd, string paramName, Actio
90
92
}
91
93
92
94
/// <summary>
93
- /// Creates a DbParameter object based on the SqlParameter and adds it to a DbCommand.
95
+ /// Adds a SqlParameter to a DbCommand.
94
96
/// This enabled the ability to provide custom types for SQL-parameters.
95
97
/// </summary>
96
98
/// <param name="cmd"></param>
97
- /// <param name="paramName"></param>
98
- /// <param name="paramValue"></param>
99
+ /// <param name="parameter"></param>
99
100
/// <returns></returns>
100
- public static DbCommand WithSqlParam ( this DbCommand cmd , string paramName , SqlParameter parameter )
101
+ public static DbCommand WithSqlParam ( this DbCommand cmd , SqlParameter parameter )
101
102
{
102
103
if ( string . IsNullOrEmpty ( cmd . CommandText ) && cmd . CommandType != System . Data . CommandType . StoredProcedure )
103
104
throw new InvalidOperationException ( "Call LoadStoredProc before using this method" ) ;
@@ -107,17 +108,33 @@ public static DbCommand WithSqlParam(this DbCommand cmd, string paramName, SqlPa
107
108
return cmd ;
108
109
}
109
110
110
- public class SprocResults
111
+ /// <summary>
112
+ /// Adds an array of SqlParameters to a DbCommand
113
+ /// </summary>
114
+ /// <param name="cmd"></param>
115
+ /// <param name="parameters"></param>
116
+ /// <returns></returns>
117
+ /// <exception cref="InvalidOperationException"></exception>
118
+ public static DbCommand WithSqlParams ( this DbCommand cmd , SqlParameter [ ] parameters )
111
119
{
120
+ if ( string . IsNullOrEmpty ( cmd . CommandText ) && cmd . CommandType != System . Data . CommandType . StoredProcedure )
121
+ throw new InvalidOperationException ( "Call LoadStoredProc before using this method" ) ;
112
122
113
- private DbDataReader _reader ;
123
+ cmd . Parameters . AddRange ( parameters ) ;
124
+
125
+ return cmd ;
126
+ }
127
+
128
+ public class SprocResults
129
+ {
130
+ private readonly DbDataReader _reader ;
114
131
115
132
public SprocResults ( DbDataReader reader )
116
133
{
117
134
_reader = reader ;
118
135
}
119
136
120
- public IList < T > ReadToList < T > ( )
137
+ public IList < T > ReadToList < T > ( ) where T : new ( )
121
138
{
122
139
return MapToList < T > ( _reader ) ;
123
140
}
@@ -147,64 +164,73 @@ public bool NextResult()
147
164
/// </summary>
148
165
/// <typeparam name="T"></typeparam>
149
166
/// <param name="dr"></param>
150
- /// <returns>IList<<typeparamref name="T"/> ></returns>
151
- private IList < T > MapToList < T > ( DbDataReader dr )
167
+ /// <returns>IList<<typeparam name="T">></typeparam ></returns>
168
+ private static IList < T > MapToList < T > ( DbDataReader dr ) where T : new ( )
152
169
{
153
170
var objList = new List < T > ( ) ;
154
171
var props = typeof ( T ) . GetRuntimeProperties ( ) . ToList ( ) ;
155
172
156
173
var colMapping = dr . GetColumnSchema ( )
157
- . Where ( x => props . Any ( y => y . Name . ToLower ( ) == x . ColumnName . ToLower ( ) ) )
158
- . ToDictionary ( key => key . ColumnName . ToLower ( ) ) ;
174
+ . Where ( x => props . Any ( y =>
175
+ string . Equals ( y . Name , x . ColumnName , StringComparison . CurrentCultureIgnoreCase ) ) )
176
+ . ToDictionary ( key => key . ColumnName . ToUpper ( ) ) ;
159
177
160
- if ( dr . HasRows )
178
+ if ( ! dr . HasRows )
179
+ return objList ;
180
+
181
+ while ( dr . Read ( ) )
161
182
{
162
- while ( dr . Read ( ) )
183
+ var obj = new T ( ) ;
184
+ foreach ( var prop in props )
163
185
{
164
- T obj = Activator . CreateInstance < T > ( ) ;
165
- foreach ( var prop in props )
166
- {
167
- if ( colMapping . ContainsKey ( prop . Name . ToLower ( ) ) )
168
- {
169
- var column = colMapping [ prop . Name . ToLower ( ) ] ;
170
-
171
- if ( column ? . ColumnOrdinal != null )
172
- {
173
- var val = dr . GetValue ( column . ColumnOrdinal . Value ) ;
174
- prop . SetValue ( obj , val == DBNull . Value ? null : val ) ;
175
- }
176
-
177
- }
178
- }
179
- objList . Add ( obj ) ;
186
+ var upperName = prop . Name . ToUpper ( ) ;
187
+
188
+ if ( ! colMapping . ContainsKey ( upperName ) )
189
+ continue ;
190
+
191
+ var column = colMapping [ upperName ] ;
192
+
193
+ if ( column ? . ColumnOrdinal == null )
194
+ continue ;
195
+
196
+ var val = dr . GetValue ( column . ColumnOrdinal . Value ) ;
197
+ prop . SetValue ( obj , val == DBNull . Value ? null : val ) ;
180
198
}
199
+
200
+ objList . Add ( obj ) ;
181
201
}
202
+
182
203
return objList ;
183
204
}
184
205
185
206
/// <summary>
186
- ///Attempts to read the first value of the first row of the resultset .
207
+ /// Attempts to read the first value of the first row of the result set .
187
208
/// </summary>
188
- private T ? MapToValue < T > ( DbDataReader dr ) where T : struct
209
+ private static T ? MapToValue < T > ( DbDataReader dr ) where T : struct
189
210
{
190
- if ( dr . HasRows )
211
+ if ( ! dr . HasRows )
212
+ return new T ? ( ) ;
213
+
214
+ if ( dr . Read ( ) )
191
215
{
192
- if ( dr . Read ( ) )
193
- {
194
- return dr . IsDBNull ( 0 ) ? new T ? ( ) : new T ? ( dr . GetFieldValue < T > ( 0 ) ) ;
195
- }
216
+ return dr . IsDBNull ( 0 ) ? new T ? ( ) : dr . GetFieldValue < T > ( 0 ) ;
196
217
}
218
+
197
219
return new T ? ( ) ;
198
220
}
199
221
}
200
222
201
223
/// <summary>
202
- /// Executes a DbDataReader and returns a list of mapped column values to the properties of <typeparamref name="T "/>
224
+ /// Executes a DbDataReader and passes the results to <paramref name="handleResults "/>
203
225
/// </summary>
204
- /// <typeparam name="T"></typeparam>
205
226
/// <param name="command"></param>
227
+ /// <param name="handleResults"></param>
228
+ /// <param name="commandBehaviour"></param>
229
+ /// <param name="manageConnection"></param>
206
230
/// <returns></returns>
207
- public static void ExecuteStoredProc ( this DbCommand command , Action < SprocResults > handleResults , System . Data . CommandBehavior commandBehaviour = System . Data . CommandBehavior . Default , bool manageConnection = true )
231
+ public static void ExecuteStoredProc ( this DbCommand command , Action < SprocResults > handleResults ,
232
+ System . Data . CommandBehavior commandBehaviour = System . Data . CommandBehavior . Default ,
233
+ bool manageConnection = true )
208
234
{
209
235
if ( handleResults == null )
210
236
{
@@ -234,12 +260,17 @@ public static void ExecuteStoredProc(this DbCommand command, Action<SprocResults
234
260
}
235
261
236
262
/// <summary>
237
- /// Executes a DbDataReader asynchronously and returns a list of mapped column values to the properties of <typeparamref name="T "/>.
263
+ /// Executes a DbDataReader asynchronously and passes the results to <paramref name="handleResults "/>
238
264
/// </summary>
239
- /// <typeparam name="T"></typeparam>
240
265
/// <param name="command"></param>
266
+ /// <param name="handleResults"></param>
267
+ /// <param name="commandBehaviour"></param>
268
+ /// <param name="ct"></param>
269
+ /// <param name="manageConnection"></param>
241
270
/// <returns></returns>
242
- public async static Task ExecuteStoredProcAsync ( this DbCommand command , Action < SprocResults > handleResults , System . Data . CommandBehavior commandBehaviour = System . Data . CommandBehavior . Default , CancellationToken ct = default ( CancellationToken ) , bool manageConnection = true )
271
+ public static async Task ExecuteStoredProcAsync ( this DbCommand command , Action < SprocResults > handleResults ,
272
+ System . Data . CommandBehavior commandBehaviour = System . Data . CommandBehavior . Default ,
273
+ CancellationToken ct = default , bool manageConnection = true )
243
274
{
244
275
if ( handleResults == null )
245
276
{
@@ -252,7 +283,8 @@ public static void ExecuteStoredProc(this DbCommand command, Action<SprocResults
252
283
await command . Connection . OpenAsync ( ct ) . ConfigureAwait ( false ) ;
253
284
try
254
285
{
255
- using ( var reader = await command . ExecuteReaderAsync ( commandBehaviour , ct ) . ConfigureAwait ( false ) )
286
+ using ( var reader = await command . ExecuteReaderAsync ( commandBehaviour , ct )
287
+ . ConfigureAwait ( false ) )
256
288
{
257
289
var sprocResults = new SprocResults ( reader ) ;
258
290
handleResults ( sprocResults ) ;
@@ -269,15 +301,57 @@ public static void ExecuteStoredProc(this DbCommand command, Action<SprocResults
269
301
}
270
302
271
303
/// <summary>
272
- /// Executes a non-query.
304
+ /// Executes a DbDataReader asynchronously and passes the results thru all <paramref name="resultActions"/>
273
305
/// </summary>
274
306
/// <param name="command"></param>
275
307
/// <param name="commandBehaviour"></param>
308
+ /// <param name="ct"></param>
309
+ /// <param name="manageConnection"></param>
310
+ /// <param name="resultActions"></param>
311
+ /// <returns></returns>
312
+ public static async Task ExecuteStoredProcAsync ( this DbCommand command ,
313
+ System . Data . CommandBehavior commandBehaviour = System . Data . CommandBehavior . Default ,
314
+ CancellationToken ct = default , bool manageConnection = true , params Action < SprocResults > [ ] resultActions )
315
+ {
316
+ if ( resultActions == null )
317
+ {
318
+ throw new ArgumentNullException ( nameof ( resultActions ) ) ;
319
+ }
320
+
321
+ using ( command )
322
+ {
323
+ if ( manageConnection && command . Connection . State == System . Data . ConnectionState . Closed )
324
+ await command . Connection . OpenAsync ( ct ) . ConfigureAwait ( false ) ;
325
+ try
326
+ {
327
+ using ( var reader = await command . ExecuteReaderAsync ( commandBehaviour , ct )
328
+ . ConfigureAwait ( false ) )
329
+ {
330
+ var sprocResults = new SprocResults ( reader ) ;
331
+
332
+ foreach ( var t in resultActions )
333
+ t ( sprocResults ) ;
334
+ }
335
+ }
336
+ finally
337
+ {
338
+ if ( manageConnection )
339
+ {
340
+ command . Connection . Close ( ) ;
341
+ }
342
+ }
343
+ }
344
+ }
345
+
346
+ /// <summary>
347
+ /// Executes a non-query.
348
+ /// </summary>
349
+ /// <param name="command"></param>
276
350
/// <param name="manageConnection"></param>
277
351
/// <returns></returns>
278
- public static int ExecuteStoredNonQuery ( this DbCommand command , System . Data . CommandBehavior commandBehaviour = System . Data . CommandBehavior . Default , bool manageConnection = true )
352
+ public static int ExecuteStoredNonQuery ( this DbCommand command , bool manageConnection = true )
279
353
{
280
- int numberOfRecordsAffected = - 1 ;
354
+ var numberOfRecordsAffected = - 1 ;
281
355
282
356
using ( command )
283
357
{
@@ -306,13 +380,13 @@ public static int ExecuteStoredNonQuery(this DbCommand command, System.Data.Comm
306
380
/// Executes a non-query asynchronously.
307
381
/// </summary>
308
382
/// <param name="command"></param>
309
- /// <param name="commandBehaviour"></param>
310
383
/// <param name="ct"></param>
311
384
/// <param name="manageConnection"></param>
312
385
/// <returns></returns>
313
- public async static Task < int > ExecuteStoredNonQueryAsync ( this DbCommand command , System . Data . CommandBehavior commandBehaviour = System . Data . CommandBehavior . Default , CancellationToken ct = default ( CancellationToken ) , bool manageConnection = true )
386
+ public static async Task < int > ExecuteStoredNonQueryAsync ( this DbCommand command , CancellationToken ct = default ,
387
+ bool manageConnection = true )
314
388
{
315
- int numberOfRecordsAffected = - 1 ;
389
+ var numberOfRecordsAffected = - 1 ;
316
390
317
391
using ( command )
318
392
{
@@ -323,7 +397,7 @@ public static int ExecuteStoredNonQuery(this DbCommand command, System.Data.Comm
323
397
324
398
try
325
399
{
326
- numberOfRecordsAffected = await command . ExecuteNonQueryAsync ( ) . ConfigureAwait ( false ) ;
400
+ numberOfRecordsAffected = await command . ExecuteNonQueryAsync ( ct ) . ConfigureAwait ( false ) ;
327
401
}
328
402
finally
329
403
{
@@ -336,6 +410,5 @@ public static int ExecuteStoredNonQuery(this DbCommand command, System.Data.Comm
336
410
337
411
return numberOfRecordsAffected ;
338
412
}
339
-
340
413
}
341
- }
414
+ }
0 commit comments