using System; using System.Collections.Generic; using System.Data; using System.Data.Common; using System.Linq; using System.Threading.Tasks; namespace Dapper { public static partial class SqlMapper { /// /// Execute a query asynchronously using .NET 4.5 Task. /// public static async Task> QueryAsync(this IDbConnection cnn, string sql, dynamic param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null) { var identity = new Identity(sql, commandType, cnn, typeof(T), param == null ? null : param.GetType(), null); var info = GetCacheInfo(identity); var cmd = (DbCommand)SetupCommand(cnn, transaction, sql, info.ParamReader, param, commandTimeout, commandType); using (var reader = await cmd.ExecuteReaderAsync()) { return ExecuteReader(reader, identity, info).ToList(); } } /// /// Maps a query to objects /// /// The first type in the recordset /// The second type in the recordset /// The return type /// /// /// /// /// /// /// The Field we should split and read the second object from (default: id) /// Number of seconds before command execution timeout /// Is it a stored proc or a batch? /// public static Task> QueryAsync(this IDbConnection cnn, string sql, Func map, dynamic param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null) { return MultiMapAsync(cnn, sql, map, param as object, transaction, buffered, splitOn, commandTimeout, commandType); } /// /// Maps a query to objects /// /// /// /// /// /// /// /// /// /// /// /// The Field we should split and read the second object from (default: id) /// Number of seconds before command execution timeout /// /// public static async Task> QueryAsync(this IDbConnection cnn, string sql, Func map, dynamic param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null) { return await MultiMapAsync(cnn, sql, map, param as object, transaction, buffered, splitOn, commandTimeout, commandType); } /// /// Perform a multi mapping query with 4 input parameters /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// public static Task> QueryAsync(this IDbConnection cnn, string sql, Func map, dynamic param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null) { return MultiMapAsync(cnn, sql, map, param as object, transaction, buffered, splitOn, commandTimeout, commandType); } /// /// Perform a multi mapping query with 5 input parameters /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// public static async Task> QueryAsync(this IDbConnection cnn, string sql, Func map, dynamic param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null) { return await MultiMapAsync(cnn, sql, map, param as object, transaction, buffered, splitOn, commandTimeout, commandType); } /// /// Perform a multi mapping query with 6 input parameters /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// public static Task> QueryAsync(this IDbConnection cnn, string sql, Func map, dynamic param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null) { return MultiMapAsync(cnn, sql, map, param as object, transaction, buffered, splitOn, commandTimeout, commandType); } /// /// Perform a multi mapping query with 7 input parameters /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// public static Task> QueryAsync(this IDbConnection cnn, string sql, Func map, dynamic param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null) { return MultiMapAsync(cnn, sql, map, param as object, transaction, buffered, splitOn, commandTimeout, commandType); } static async Task> MultiMapAsync(this IDbConnection cnn, string sql, object map, object param, IDbTransaction transaction, bool buffered, string splitOn, int? commandTimeout, CommandType? commandType) { var identity = new Identity(sql, commandType, cnn, typeof(TFirst), (object)param == null ? null : ((object)param).GetType(), new[] { typeof(TFirst), typeof(TSecond), typeof(TThird), typeof(TFourth), typeof(TFifth), typeof(TSixth), typeof(TSeventh) }); var info = GetCacheInfo(identity); var cmd = (DbCommand)SetupCommand(cnn, transaction, sql, info.ParamReader, param, commandTimeout, commandType); using (var reader = await cmd.ExecuteReaderAsync()) { var results = MultiMapImpl(null, null, map, null, null, splitOn, null, null, reader, identity); return buffered ? results.ToList() : results; } } private static IEnumerable ExecuteReader(IDataReader reader, Identity identity, CacheInfo info) { var tuple = info.Deserializer; int hash = GetColumnHash(reader); if (tuple.Func == null || tuple.Hash != hash) { tuple = info.Deserializer = new DeserializerState(hash, GetDeserializer(typeof(T), reader, 0, -1, false)); SetQueryCache(identity, info); } var func = tuple.Func; while (reader.Read()) { yield return (T)func(reader); } } } }