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);
}
}
}
}