using System; using System.Collections.Generic; using System.Data; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Dapper { public abstract partial class Database where TDatabase : Database, new() { public partial class Table { /// /// Insert a row into the db asynchronously. /// /// Either DynamicParameters or an anonymous type or concrete type. /// The Id of the inserted row. public virtual async Task InsertAsync(dynamic data) { var o = (object)data; List paramNames = GetParamNames(o); paramNames.Remove("Id"); string cols = string.Join(",", paramNames); string colsParams = string.Join(",", paramNames.Select(p => "@" + p)); var sql = "set nocount on insert " + TableName + " (" + cols + ") values (" + colsParams + ") select cast(scope_identity() as int)"; return (await database.QueryAsync(sql, o).ConfigureAwait(false)).Single(); } /// /// Update a record in the DB asynchronously. /// /// The Id of the record to update. /// The new record. /// The number of affected rows. public Task UpdateAsync(TId id, dynamic data) { List paramNames = GetParamNames((object)data); var builder = new StringBuilder(); builder.Append("update ").Append(TableName).Append(" set "); builder.AppendLine(string.Join(",", paramNames.Where(n => n != "Id").Select(p => p + "= @" + p))); builder.Append("where Id = @Id"); var parameters = new DynamicParameters(data); parameters.Add("Id", id); return database.ExecuteAsync(builder.ToString(), parameters); } /// /// Asynchronously deletes a record for the DB. /// /// The Id of the record to delete. /// The number of rows affected. public async Task DeleteAsync(TId id) => (await database.ExecuteAsync("delete from " + TableName + " where Id = @id", new { id }).ConfigureAwait(false)) > 0; /// /// Asynchronously gets a record with a particular Id from the DB. /// /// The primary key of the table to fetch. /// The record with the specified Id. public Task GetAsync(TId id) => database.QueryFirstOrDefaultAsync("select * from " + TableName + " where Id = @id", new { id }); /// /// Asynchronously gets the first row from this table (order determined by the database provider). /// /// Data from the first table row. public virtual Task FirstAsync() => database.QueryFirstOrDefaultAsync("select top 1 * from " + TableName); /// /// Asynchronously gets the all rows from this table. /// /// Data from all table rows. public Task> AllAsync() => database.QueryAsync("select * from " + TableName); } /// /// Asynchronously executes SQL against the current database. /// /// The SQL to execute. /// The parameters to use. /// The number of rows affected. public Task ExecuteAsync(string sql, dynamic param = null) => _connection.ExecuteAsync(sql, param as object, Transaction, _commandTimeout); /// /// Asynchronously queries the current database. /// /// The type to return. /// The SQL to execute. /// The parameters to use. /// An enumerable of for the rows fetched. public Task> QueryAsync(string sql, dynamic param = null) => _connection.QueryAsync(sql, param as object, Transaction, _commandTimeout); /// /// Asynchronously queries the current database for a single record. /// /// The type to return. /// The SQL to execute. /// The parameters to use. /// An enumerable of for the rows fetched. public Task QueryFirstOrDefaultAsync(string sql, dynamic param = null) => _connection.QueryFirstOrDefaultAsync(sql, param as object, Transaction, _commandTimeout); /// /// Perform an asynchronous multi-mapping query with 2 input types. /// This returns a single type, combined from the raw types via . /// /// The first type in the recordset. /// The second type in the recordset. /// The combined type to return. /// The SQL to execute for this query. /// The function to map row types to the return type. /// The parameters to use for this query. /// The transaction to use for this query. /// Whether to buffer the results in memory. /// The field we should split and read the second object from (default: "Id"). /// Number of seconds before command execution timeout. /// An enumerable of . public Task> QueryAsync(string sql, Func map, dynamic param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null) => _connection.QueryAsync(sql, map, param as object, transaction, buffered, splitOn, commandTimeout); /// /// Perform an asynchronous multi-mapping query with 3 input types. /// This returns a single type, combined from the raw types via . /// /// The first type in the recordset. /// The second type in the recordset. /// The third type in the recordset. /// The combined type to return. /// The SQL to execute for this query. /// The function to map row types to the return type. /// The parameters to use for this query. /// The transaction to use for this query. /// Whether to buffer the results in memory. /// The field we should split and read the second object from (default: "Id"). /// Number of seconds before command execution timeout. /// An enumerable of . public Task> QueryAsync(string sql, Func map, dynamic param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null) => _connection.QueryAsync(sql, map, param as object, transaction, buffered, splitOn, commandTimeout); /// /// Perform an asynchronous multi-mapping query with 4 input types. /// This returns a single type, combined from the raw types via . /// /// The first type in the recordset. /// The second type in the recordset. /// The third type in the recordset. /// The fourth type in the recordset. /// The combined type to return. /// The SQL to execute for this query. /// The function to map row types to the return type. /// The parameters to use for this query. /// The transaction to use for this query. /// Whether to buffer the results in memory. /// The field we should split and read the second object from (default: "Id"). /// Number of seconds before command execution timeout. /// An enumerable of . public Task> QueryAsync(string sql, Func map, dynamic param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null) => _connection.QueryAsync(sql, map, param as object, transaction, buffered, splitOn, commandTimeout); /// /// Perform an asynchronous multi-mapping query with 5 input types. /// This returns a single type, combined from the raw types via . /// /// The first type in the recordset. /// The second type in the recordset. /// The third type in the recordset. /// The fourth type in the recordset. /// The fifth type in the recordset. /// The combined type to return. /// The SQL to execute for this query. /// The function to map row types to the return type. /// The parameters to use for this query. /// The transaction to use for this query. /// Whether to buffer the results in memory. /// The field we should split and read the second object from (default: "Id"). /// Number of seconds before command execution timeout. /// An enumerable of . public Task> QueryAsync(string sql, Func map, dynamic param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null) => _connection.QueryAsync(sql, map, param as object, transaction, buffered, splitOn, commandTimeout); /// /// Execute a query asynchronously using Task. /// /// The SQL to execute. /// The parameters to use. /// Note: each row can be accessed via "dynamic", or by casting to an IDictionary<string,object> public Task> QueryAsync(string sql, dynamic param = null) => _connection.QueryAsync(sql, param as object, Transaction); /// /// Execute a command that returns multiple result sets, and access each in turn. /// /// The SQL to execute for this query. /// The parameters to use for this query. /// The transaction to use for this query. /// Number of seconds before command execution timeout. /// Is it a stored proc or a batch? public Task QueryMultipleAsync(string sql, dynamic param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null) => SqlMapper.QueryMultipleAsync(_connection, sql, param, transaction, commandTimeout, commandType); } }