Sto imparando come Dapper sta lavorando dietro le quinte.Clausola `using` annidata di Dapper - Chiarimento?
Tuttavia ho visto questo schema di smaltimento che non mi è compreso.
Circa in generale -this è come QueryAsync
è implementato:
/*1*/ public async Task<IEnumerable<T>> QueryAsync<T>(string sql, Func<IDataRecord, T> projector, DbConnection _conn, dynamic param = null)
/*2*/ {
/*3*/
/*4*/ DbDataReader reader = null;
/*5*/ bool wasClosed = _conn.State == ConnectionState.Closed;
/*6*/ try
/*7*/ {
/*8*/
/*9*/ using (var cmd = _conn.CreateCommand())
/*10*/ {
/*11*/ if (param!=null)
/*12*/ foreach (var prop in param.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public))
/*13*/ {
/*14*/ var parameter = cmd.CreateParameter();
/*15*/ parameter.ParameterName = prop.Name;
/*16*/ parameter.Value = prop.GetValue(param, null);
/*17*/ cmd.Parameters.Add(parameter);
/*18*/ }
/*19*/
/*20*/ await _conn.OpenAsync().ConfigureAwait(false);
/*21*/ cmd.CommandTimeout = 100000;
/*22*/ cmd.CommandText = sql;
/*23*/ reader = await cmd.ExecuteReaderAsync().ConfigureAwait(false);
/*24*/ List<T> buffer = new List<T>();
/*25*/ while (await reader.ReadAsync().ConfigureAwait(false)) buffer.Add(projector(reader));
/*26*/ return buffer;
/*27*/ }
/*28*/
/*29*/ }
/*30*/ finally
/*31*/ {
/*32*/ using (reader) { }
/*33*/ if (wasClosed) _conn.Close();
/*34*/ }
/*35*/ }
posso capire perché non ha usato using
tramite la connessione, è perché voleva condizionale chiudere la connessione via la variabile wasClosed.
Per farlo - deve utilizzare la clausola try/finally
. (quindi la chiusura condizionale sarà nella clausola finally
)
Ma la mia domanda riguarda la linea n. 32.
Invece di fare using at the finally clause, che poteva fare:
using (DbDataReader reader = await cmd.ExecuteReaderAsync().ConfigureAwait(false))
{
List<T> buffer = new List<T>();
while (await reader.ReadAsync().ConfigureAwait(false)) buffer.Add(projector(reader));
return buffer;
}
Quindi la clausola di finally
è lasciato con:
finally
{
//using (reader) { } //removed
if (wasClosed) _conn.Close();
}
Domanda
ho visto questa clausola using
in una clausola definitiva molte volte in dapper.
Mi manca qualcosa qui, ma cosa fa questo schema che il mio suggerimento non ha?
Questo sembra un difetto. La tua proposta è migliore. Probabilmente non c'è una buona ragione per questo. – usr