private static async Task <T> ExecuteScalarImplAsync <T>(IDbConnection cnn, CommandDefinition command) { Action <IDbCommand, DynamicParameters> paramReader = null; object param = command.Parameters; if (param != null) { var identity = new Identity(command.CommandText, command.CommandType, cnn, null, param.GetType()); paramReader = GetCacheInfo(identity).ParamReader; } DbCommand cmd = null; bool needClose = cnn.State == ConnectionState.Closed; object result; try { cmd = command.TrySetupAsyncCommand(cnn, paramReader); if (needClose) { await cnn.TryOpenAsync(default(CancellationToken)).ConfigureAwait(false); } result = await cmd.ExecuteScalarAsync(default(CancellationToken)).ConfigureAwait(false); } finally { if (needClose) { cnn.Close(); } cmd?.Dispose(); } return(Parse <T>(result)); }
/* * ExecuteImpl */ private static async Task <int> ExecuteImplAsync(IDbConnection cnn, CommandDefinition command, DynamicParameters param) { var identity = new Identity(command.CommandText, command.CommandType, cnn, null, param?.GetType()); var info = GetCacheInfo(identity); bool needClose = cnn.State == ConnectionState.Closed; using (var cmd = command.TrySetupAsyncCommand(cnn, info.ParamReader)) { try { if (needClose) { await cnn.TryOpenAsync(default(CancellationToken)).ConfigureAwait(false); } var result = await cmd.ExecuteNonQueryAsync(default(CancellationToken)).ConfigureAwait(false); return(result); } finally { if (needClose) { cnn.Close(); } } } }
private static async Task <IEnumerable <T> > QueryAsync <T>(this IDbConnection cnn, Type effectiveType, CommandDefinition command) { DynamicParameters param = command.Parameters; var identity = new Identity(command.CommandText, command.CommandType, cnn, effectiveType, param?.GetType()); var info = GetCacheInfo(identity); bool needClose = cnn.State == ConnectionState.Closed; using (var cmd = command.TrySetupAsyncCommand(cnn, info.ParamReader)) { DbDataReader reader = null; try { if (needClose) { await cnn.TryOpenAsync(default(CancellationToken)).ConfigureAwait(false); } reader = await ExecuteReaderWithFlagsFallbackAsync(cmd, needClose, CommandBehavior.SequentialAccess | CommandBehavior.SingleResult, default(CancellationToken)).ConfigureAwait(false); var tuple = info.Deserializer; int hash = GetColumnHash(reader); if (tuple.Func == null || tuple.Hash != hash) { if (reader.FieldCount == 0) { return(Enumerable.Empty <T>()); } info.Deserializer = new DeserializerState(hash, GetDeserializer(effectiveType, reader, 0, -1, false)); tuple = info.Deserializer; } var func = tuple.Func; if (command.Buffered) { var buffer = new List <T>(); var convertToType = Nullable.GetUnderlyingType(effectiveType) ?? effectiveType; while (await reader.ReadAsync(default(CancellationToken)).ConfigureAwait(false)) { object val = func(reader); if (val == null || val is T) { buffer.Add((T)val); } else { buffer.Add((T)Convert.ChangeType(val, convertToType, CultureInfo.InvariantCulture)); } } while (await reader.NextResultAsync(default(CancellationToken)).ConfigureAwait(false)) { /* ignore subsequent result sets */ } return(buffer); } else { // can't use ReadAsync / cancellation; but this will have to do needClose = false; // don't close if handing back an open reader; rely on the command-behavior var deferred = ExecuteReaderSync <T>(reader, func, command.Parameters); reader = null; // to prevent it being disposed before the caller gets to see it return(deferred); } } finally { using (reader) { /* dispose if non-null */ } if (needClose) { cnn.Close(); } } } }
/******************************************************************************************/ /// <summary> /// 查询单行 /// </summary> private static async Task <T> QueryRowAsync <T>(this IDbConnection cnn, RowEnum row, Type effectiveType, CommandDefinition command) { DynamicParameters param = command.Parameters; var identity = new Identity(command.CommandText, command.CommandType, cnn, effectiveType, param?.GetType()); var info = GetCacheInfo(identity); bool needClose = cnn.State == ConnectionState.Closed; using (var cmd = command.TrySetupAsyncCommand(cnn, info.ParamReader)) { DbDataReader reader = null; try { if (needClose) { await cnn.TryOpenAsync(default(CancellationToken)).ConfigureAwait(false); } reader = await ExecuteReaderWithFlagsFallbackAsync(cmd, needClose, (row & RowEnum.Single) != 0 ?CommandBehavior.SequentialAccess | CommandBehavior.SingleResult // need to allow multiple rows, to check fail condition : CommandBehavior.SequentialAccess | CommandBehavior.SingleResult | CommandBehavior.SingleRow, default(CancellationToken)).ConfigureAwait(false); T result = default(T); if (await reader.ReadAsync(default(CancellationToken)).ConfigureAwait(false) && reader.FieldCount != 0) { var tuple = info.Deserializer; int hash = GetColumnHash(reader); if (tuple.Func == null || tuple.Hash != hash) { tuple = info.Deserializer = new DeserializerState(hash, GetDeserializer(effectiveType, reader, 0, -1, false)); } var func = tuple.Func; object val = func(reader); if (val == null || val is T) { result = (T)val; } else { var convertToType = Nullable.GetUnderlyingType(effectiveType) ?? effectiveType; result = (T)Convert.ChangeType(val, convertToType, CultureInfo.InvariantCulture); } if ((row & RowEnum.Single) != 0 && await reader.ReadAsync(default(CancellationToken)).ConfigureAwait(false)) { ThrowMultipleRows(row); } while (await reader.ReadAsync(default(CancellationToken)).ConfigureAwait(false)) { /* ignore rows after the first */ } } else if ((row & RowEnum.FirstOrDefault) == 0) // demanding a row, and don't have one { ThrowZeroRows(row); } while (await reader.NextResultAsync(default(CancellationToken)).ConfigureAwait(false)) { /* ignore result sets after the first */ } return(result); } finally { using (reader) { /* dispose if non-null */ } if (needClose) { cnn.Close(); } } } }