11#if EFCORE && ! EFCORE_2X
2+ using System ;
3+ using System . Collections . Generic ;
4+ using System . Data ;
5+ using System . Linq ;
6+ using System . Reflection ;
7+ using System . Threading ;
8+ using System . Threading . Tasks ;
9+ using Microsoft . EntityFrameworkCore ;
10+ using Microsoft . EntityFrameworkCore . Infrastructure ;
11+ using Microsoft . EntityFrameworkCore . Storage ;
212
313namespace EntityFrameworkExtras . EFCore
414{
515 public static partial class DatabaseExtensions
616 {
17+ /// <summary>
18+ /// Executes the specified stored procedure against a database.
19+ /// </summary>
20+ /// <param name="database">The database to execute against.</param>
21+ /// <param name="storedProcedure">The stored procedure to execute.</param>
22+ public static void ExecuteStoredProcedure ( this DatabaseFacade database , object storedProcedure )
23+ {
24+ if ( storedProcedure == null )
25+ throw new ArgumentNullException ( "storedProcedure" ) ;
26+
27+ var info = StoredProcedureParser . BuildStoredProcedureInfo ( storedProcedure ) ;
28+
29+ database . ExecuteSqlRawAsync ( info . Sql , info . SqlParameters ) ;
30+
31+ SetOutputParameterValues ( info . SqlParameters , storedProcedure ) ;
32+ }
33+
34+ /// <summary>
35+ /// Executes the specified stored procedure against a database
36+ /// and returns an enumerable of T representing the data returned.
37+ /// </summary>
38+ /// <typeparam name="T">Type of the data returned from the stored procedure.</typeparam>
39+ /// <param name="database">The database to execute against.</param>
40+ /// <param name="storedProcedure">The stored procedure to execute.</param>
41+ /// <param name="cancellationToken">The cancellation token.</param>
42+ /// <returns></returns>
43+ public static async Task ExecuteStoredProcedureAsync ( this DatabaseFacade database , object storedProcedure , CancellationToken cancellationToken = default )
44+ {
45+ if ( storedProcedure == null )
46+ throw new ArgumentNullException ( "storedProcedure" ) ;
47+
48+ var info = StoredProcedureParser . BuildStoredProcedureInfo ( storedProcedure ) ;
49+
50+ var listParam = info . SqlParameters != null && info . SqlParameters . Length > 0
51+ ? info . SqlParameters . ToList ( )
52+ : null ;
53+
54+ var task = await database . ExecuteSqlRawAsync ( info . Sql , listParam , cancellationToken ) . ConfigureAwait ( false ) ;
55+
56+ SetOutputParameterValues ( info . SqlParameters , storedProcedure ) ;
57+ }
58+
59+ /// <summary>
60+ /// Executes the specified stored procedure against a database
61+ /// and returns an enumerable of T representing the data returned.
62+ /// </summary>
63+ /// <typeparam name="T">Type of the data returned from the stored procedure.</typeparam>
64+ /// <param name="database">The database to execute against.</param>
65+ /// <param name="storedProcedure">The stored procedure to execute.</param>
66+ /// <returns></returns>
67+ public static IEnumerable < T > ExecuteStoredProcedure < T > ( this DatabaseFacade database , object storedProcedure )
68+ {
69+ if ( storedProcedure == null )
70+ throw new ArgumentNullException ( "storedProcedure" ) ;
71+
72+
73+ List < T > result = new List < T > ( ) ;
74+ var info = StoredProcedureParser . BuildStoredProcedureInfo ( storedProcedure ) ;
75+
76+
77+ // from : https://github.com/Fodsuk/EntityFrameworkExtras/pull/23/commits/dce354304aa9a95750f7d2559d1b002444ac46f7
78+ using ( var command = database . GetDbConnection ( ) . CreateCommand ( ) )
79+ {
80+ command . CommandText = info . Sql ;
81+ command . CommandType = CommandType . Text ;
82+ command . Parameters . AddRange ( info . SqlParameters ) ;
83+ command . Transaction = database . CurrentTransaction ? . GetDbTransaction ( ) ;
84+ database . OpenConnection ( ) ;
85+
86+ using ( var resultReader = command . ExecuteReader ( ) )
87+ {
88+ T obj = default ( T ) ;
89+
90+ while ( resultReader . Read ( ) )
91+ {
92+ obj = Activator . CreateInstance < T > ( ) ;
93+ foreach ( PropertyInfo prop in obj . GetType ( ) . GetProperties ( ) )
94+ {
95+ var val = GetValue ( resultReader , prop . Name ) ;
96+ if ( ! object . Equals ( val , DBNull . Value ) )
97+ {
98+ prop . SetValue ( obj , val , null ) ;
99+ }
100+ }
101+
102+ result . Add ( obj ) ;
103+ }
104+ }
105+
106+ }
107+
108+ SetOutputParameterValues ( info . SqlParameters , storedProcedure ) ;
109+
110+ return result ;
111+ }
112+
113+ /// <summary>
114+ /// Executes the specified stored procedure against a database asyncrounously
115+ /// and returns an enumerable of T representing the data returned.
116+ /// </summary>
117+ /// <typeparam name="T">Type of the data returned from the stored procedure.</typeparam>
118+ /// <param name="database">The database to execute against.</param>
119+ /// <param name="storedProcedure">The stored procedure to execute.</param>
120+ /// <param name="cancellationToken">The cancellation token.</param>
121+ /// <returns></returns>
122+ public static async Task < IEnumerable < T > > ExecuteStoredProcedureAsync < T > ( this DatabaseFacade database , object storedProcedure , CancellationToken cancellationToken = default )
123+ {
124+ if ( storedProcedure == null )
125+ throw new ArgumentNullException ( "storedProcedure" ) ;
126+
127+
128+ List < T > result = new List < T > ( ) ;
129+ var info = StoredProcedureParser . BuildStoredProcedureInfo ( storedProcedure ) ;
130+
131+
132+ // from : https://github.com/Fodsuk/EntityFrameworkExtras/pull/23/commits/dce354304aa9a95750f7d2559d1b002444ac46f7
133+ using ( var command = database . GetDbConnection ( ) . CreateCommand ( ) )
134+ {
135+ command . CommandText = info . Sql ;
136+ command . CommandType = CommandType . Text ;
137+ command . Parameters . AddRange ( info . SqlParameters ) ;
138+ command . Transaction = database . CurrentTransaction ? . GetDbTransaction ( ) ;
139+ database . OpenConnection ( ) ;
140+
141+ using ( var resultReader = await command . ExecuteReaderAsync ( cancellationToken ) . ConfigureAwait ( false ) )
142+ {
143+ T obj = default ( T ) ;
144+
145+ while ( await resultReader . ReadAsync ( cancellationToken ) . ConfigureAwait ( false ) )
146+ {
147+ obj = Activator . CreateInstance < T > ( ) ;
148+ foreach ( PropertyInfo prop in obj . GetType ( ) . GetProperties ( ) )
149+ {
150+ var val = GetValue ( resultReader , prop . Name ) ;
151+ if ( ! object . Equals ( val , DBNull . Value ) )
152+ {
153+ prop . SetValue ( obj , val , null ) ;
154+ }
155+ }
156+
157+ result . Add ( obj ) ;
158+ }
159+ }
160+
161+ }
162+
163+ SetOutputParameterValues ( info . SqlParameters , storedProcedure ) ;
164+
165+ return result ;
166+ }
167+
168+ /// <summary>
169+ /// Executes the specified stored procedure against a database
170+ /// and returns the first or default value
171+ /// </summary>
172+ /// <typeparam name="T">Type of the data returned from the stored procedure.</typeparam>
173+ /// <param name="database">The database to execute against.</param>
174+ /// <param name="storedProcedure">The stored procedure to execute.</param>
175+ /// <returns></returns>
176+ public static T ExecuteStoredProcedureFirstOrDefault < T > ( this DatabaseFacade database , object storedProcedure )
177+ {
178+ return database . ExecuteStoredProcedure < T > ( storedProcedure ) . FirstOrDefault ( ) ;
179+ }
180+
181+ // <summary>
182+ /// Executes the specified stored procedure against a database asynchronously
183+ /// and returns the first or default value
184+ /// </summary>
185+ /// <typeparam name="T">Type of the data returned from the stored procedure.</typeparam>
186+ /// <param name="database">The database to execute against.</param>
187+ /// <param name="storedProcedure">The stored procedure to execute.</param>
188+ /// <param name="cancellationToken">The cancellation token.</param>
189+ /// <returns></returns>
190+ public static async Task < T > ExecuteStoredProcedureFirstOrDefaultAsync < T > ( this DatabaseFacade database , object storedProcedure , CancellationToken cancellationToken = default )
191+ {
192+ var executed = await database . ExecuteStoredProcedureAsync < T > ( storedProcedure , cancellationToken ) . ConfigureAwait ( false ) ;
193+
194+ return executed . FirstOrDefault ( ) ;
195+ }
7196 }
8197}
9198#endif
0 commit comments