@@ -24,11 +24,10 @@ public static class EFExtensions
2424 /// <param name="prependDefaultSchema">Prepend the default schema name to <paramref name="storedProcName"/> if explicitly defined in <paramref name="context"/></param>
2525 /// <param name="commandTimeout">Command timeout in seconds. Default is 30.</param>
2626 /// <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 )
2829 {
29-
3030 var cmd = context . Database . GetDbConnection ( ) . CreateCommand ( ) ;
31-
3231 cmd . CommandTimeout = commandTimeout ;
3332
3433 if ( prependDefaultSchema )
@@ -56,15 +55,17 @@ public static DbCommand LoadStoredProc(this DbContext context, string storedProc
5655 /// <param name="cmd"></param>
5756 /// <param name="paramName"></param>
5857 /// <param name="paramValue"></param>
58+ /// <param name="configureParam"></param>
5959 /// <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 )
6162 {
6263 if ( string . IsNullOrEmpty ( cmd . CommandText ) && cmd . CommandType != System . Data . CommandType . StoredProcedure )
6364 throw new InvalidOperationException ( "Call LoadStoredProc before using this method" ) ;
6465
6566 var param = cmd . CreateParameter ( ) ;
6667 param . ParameterName = paramName ;
67- param . Value = ( paramValue != null ? paramValue : DBNull . Value ) ;
68+ param . Value = paramValue ?? DBNull . Value ;
6869 configureParam ? . Invoke ( param ) ;
6970 cmd . Parameters . Add ( param ) ;
7071 return cmd ;
@@ -75,9 +76,10 @@ public static DbCommand WithSqlParam(this DbCommand cmd, string paramName, objec
7576 /// </summary>
7677 /// <param name="cmd"></param>
7778 /// <param name="paramName"></param>
78- /// <param name="paramValue "></param>
79+ /// <param name="configureParam "></param>
7980 /// <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 )
8183 {
8284 if ( string . IsNullOrEmpty ( cmd . CommandText ) && cmd . CommandType != System . Data . CommandType . StoredProcedure )
8385 throw new InvalidOperationException ( "Call LoadStoredProc before using this method" ) ;
@@ -90,14 +92,13 @@ public static DbCommand WithSqlParam(this DbCommand cmd, string paramName, Actio
9092 }
9193
9294 /// <summary>
93- /// Creates a DbParameter object based on the SqlParameter and adds it to a DbCommand.
95+ /// Adds a SqlParameter to a DbCommand.
9496 /// This enabled the ability to provide custom types for SQL-parameters.
9597 /// </summary>
9698 /// <param name="cmd"></param>
97- /// <param name="paramName"></param>
98- /// <param name="paramValue"></param>
99+ /// <param name="parameter"></param>
99100 /// <returns></returns>
100- public static DbCommand WithSqlParam ( this DbCommand cmd , string paramName , SqlParameter parameter )
101+ public static DbCommand WithSqlParam ( this DbCommand cmd , SqlParameter parameter )
101102 {
102103 if ( string . IsNullOrEmpty ( cmd . CommandText ) && cmd . CommandType != System . Data . CommandType . StoredProcedure )
103104 throw new InvalidOperationException ( "Call LoadStoredProc before using this method" ) ;
@@ -107,17 +108,33 @@ public static DbCommand WithSqlParam(this DbCommand cmd, string paramName, SqlPa
107108 return cmd ;
108109 }
109110
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 )
111119 {
120+ if ( string . IsNullOrEmpty ( cmd . CommandText ) && cmd . CommandType != System . Data . CommandType . StoredProcedure )
121+ throw new InvalidOperationException ( "Call LoadStoredProc before using this method" ) ;
112122
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 ;
114131
115132 public SprocResults ( DbDataReader reader )
116133 {
117134 _reader = reader ;
118135 }
119136
120- public IList < T > ReadToList < T > ( )
137+ public IList < T > ReadToList < T > ( ) where T : new ( )
121138 {
122139 return MapToList < T > ( _reader ) ;
123140 }
@@ -147,64 +164,73 @@ public bool NextResult()
147164 /// </summary>
148165 /// <typeparam name="T"></typeparam>
149166 /// <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 ( )
152169 {
153170 var objList = new List < T > ( ) ;
154171 var props = typeof ( T ) . GetRuntimeProperties ( ) . ToList ( ) ;
155172
156173 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 ( ) ) ;
159177
160- if ( dr . HasRows )
178+ if ( ! dr . HasRows )
179+ return objList ;
180+
181+ while ( dr . Read ( ) )
161182 {
162- while ( dr . Read ( ) )
183+ var obj = new T ( ) ;
184+ foreach ( var prop in props )
163185 {
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 ) ;
180198 }
199+
200+ objList . Add ( obj ) ;
181201 }
202+
182203 return objList ;
183204 }
184205
185206 /// <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 .
187208 /// </summary>
188- private T ? MapToValue < T > ( DbDataReader dr ) where T : struct
209+ private static T ? MapToValue < T > ( DbDataReader dr ) where T : struct
189210 {
190- if ( dr . HasRows )
211+ if ( ! dr . HasRows )
212+ return new T ? ( ) ;
213+
214+ if ( dr . Read ( ) )
191215 {
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 ) ;
196217 }
218+
197219 return new T ? ( ) ;
198220 }
199221 }
200222
201223 /// <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 "/>
203225 /// </summary>
204- /// <typeparam name="T"></typeparam>
205226 /// <param name="command"></param>
227+ /// <param name="handleResults"></param>
228+ /// <param name="commandBehaviour"></param>
229+ /// <param name="manageConnection"></param>
206230 /// <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 )
208234 {
209235 if ( handleResults == null )
210236 {
@@ -234,12 +260,17 @@ public static void ExecuteStoredProc(this DbCommand command, Action<SprocResults
234260 }
235261
236262 /// <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 "/>
238264 /// </summary>
239- /// <typeparam name="T"></typeparam>
240265 /// <param name="command"></param>
266+ /// <param name="handleResults"></param>
267+ /// <param name="commandBehaviour"></param>
268+ /// <param name="ct"></param>
269+ /// <param name="manageConnection"></param>
241270 /// <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 )
243274 {
244275 if ( handleResults == null )
245276 {
@@ -252,7 +283,8 @@ public static void ExecuteStoredProc(this DbCommand command, Action<SprocResults
252283 await command . Connection . OpenAsync ( ct ) . ConfigureAwait ( false ) ;
253284 try
254285 {
255- using ( var reader = await command . ExecuteReaderAsync ( commandBehaviour , ct ) . ConfigureAwait ( false ) )
286+ using ( var reader = await command . ExecuteReaderAsync ( commandBehaviour , ct )
287+ . ConfigureAwait ( false ) )
256288 {
257289 var sprocResults = new SprocResults ( reader ) ;
258290 handleResults ( sprocResults ) ;
@@ -269,15 +301,57 @@ public static void ExecuteStoredProc(this DbCommand command, Action<SprocResults
269301 }
270302
271303 /// <summary>
272- /// Executes a non-query.
304+ /// Executes a DbDataReader asynchronously and passes the results thru all <paramref name="resultActions"/>
273305 /// </summary>
274306 /// <param name="command"></param>
275307 /// <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>
276350 /// <param name="manageConnection"></param>
277351 /// <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 )
279353 {
280- int numberOfRecordsAffected = - 1 ;
354+ var numberOfRecordsAffected = - 1 ;
281355
282356 using ( command )
283357 {
@@ -306,13 +380,13 @@ public static int ExecuteStoredNonQuery(this DbCommand command, System.Data.Comm
306380 /// Executes a non-query asynchronously.
307381 /// </summary>
308382 /// <param name="command"></param>
309- /// <param name="commandBehaviour"></param>
310383 /// <param name="ct"></param>
311384 /// <param name="manageConnection"></param>
312385 /// <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 )
314388 {
315- int numberOfRecordsAffected = - 1 ;
389+ var numberOfRecordsAffected = - 1 ;
316390
317391 using ( command )
318392 {
@@ -323,7 +397,7 @@ public static int ExecuteStoredNonQuery(this DbCommand command, System.Data.Comm
323397
324398 try
325399 {
326- numberOfRecordsAffected = await command . ExecuteNonQueryAsync ( ) . ConfigureAwait ( false ) ;
400+ numberOfRecordsAffected = await command . ExecuteNonQueryAsync ( ct ) . ConfigureAwait ( false ) ;
327401 }
328402 finally
329403 {
@@ -336,6 +410,5 @@ public static int ExecuteStoredNonQuery(this DbCommand command, System.Data.Comm
336410
337411 return numberOfRecordsAffected ;
338412 }
339-
340413 }
341- }
414+ }
0 commit comments