forked from DapperLib/Dapper
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathDatabase.Async.cs
211 lines (191 loc) · 13.4 KB
/
Database.Async.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
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<TDatabase> where TDatabase : Database<TDatabase>, new()
{
public partial class Table<T, TId>
{
/// <summary>
/// Insert a row into the db asynchronously.
/// </summary>
/// <param name="data">Either DynamicParameters or an anonymous type or concrete type.</param>
/// <returns>The Id of the inserted row.</returns>
public virtual async Task<int?> InsertAsync(dynamic data)
{
var o = (object)data;
List<string> 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<int?>(sql, o).ConfigureAwait(false)).Single();
}
/// <summary>
/// Update a record in the DB asynchronously.
/// </summary>
/// <param name="id">The Id of the record to update.</param>
/// <param name="data">The new record.</param>
/// <returns>The number of affected rows.</returns>
public Task<int> UpdateAsync(TId id, dynamic data)
{
List<string> 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);
}
/// <summary>
/// Asynchronously deletes a record for the DB.
/// </summary>
/// <param name="id">The Id of the record to delete.</param>
/// <returns>The number of rows affected.</returns>
public async Task<bool> DeleteAsync(TId id) =>
(await database.ExecuteAsync("delete from " + TableName + " where Id = @id", new { id }).ConfigureAwait(false)) > 0;
/// <summary>
/// Asynchronously gets a record with a particular Id from the DB.
/// </summary>
/// <param name="id">The primary key of the table to fetch.</param>
/// <returns>The record with the specified Id.</returns>
public Task<T> GetAsync(TId id) =>
database.QueryFirstOrDefaultAsync<T>("select * from " + TableName + " where Id = @id", new { id });
/// <summary>
/// Asynchronously gets the first row from this table (order determined by the database provider).
/// </summary>
/// <returns>Data from the first table row.</returns>
public virtual Task<T> FirstAsync() =>
database.QueryFirstOrDefaultAsync<T>("select top 1 * from " + TableName);
/// <summary>
/// Asynchronously gets the all rows from this table.
/// </summary>
/// <returns>Data from all table rows.</returns>
public Task<IEnumerable<T>> AllAsync() =>
database.QueryAsync<T>("select * from " + TableName);
}
/// <summary>
/// Asynchronously executes SQL against the current database.
/// </summary>
/// <param name="sql">The SQL to execute.</param>
/// <param name="param">The parameters to use.</param>
/// <returns>The number of rows affected.</returns>
public Task<int> ExecuteAsync(string sql, dynamic param = null) =>
_connection.ExecuteAsync(sql, param as object, _transaction, _commandTimeout);
/// <summary>
/// Asynchronously queries the current database.
/// </summary>
/// <typeparam name="T">The type to return.</typeparam>
/// <param name="sql">The SQL to execute.</param>
/// <param name="param">The parameters to use.</param>
/// <returns>An enumerable of <typeparamref name="T"/> for the rows fetched.</returns>
public Task<IEnumerable<T>> QueryAsync<T>(string sql, dynamic param = null) =>
_connection.QueryAsync<T>(sql, param as object, _transaction, _commandTimeout);
/// <summary>
/// Asynchronously queries the current database for a single record.
/// </summary>
/// <typeparam name="T">The type to return.</typeparam>
/// <param name="sql">The SQL to execute.</param>
/// <param name="param">The parameters to use.</param>
/// <returns>An enumerable of <typeparamref name="T"/> for the rows fetched.</returns>
public Task<T> QueryFirstOrDefaultAsync<T>(string sql, dynamic param = null) =>
_connection.QueryFirstOrDefaultAsync<T>(sql, param as object, _transaction, _commandTimeout);
/// <summary>
/// Perform an asynchronous multi-mapping query with 2 input types.
/// This returns a single type, combined from the raw types via <paramref name="map"/>.
/// </summary>
/// <typeparam name="TFirst">The first type in the recordset.</typeparam>
/// <typeparam name="TSecond">The second type in the recordset.</typeparam>
/// <typeparam name="TReturn">The combined type to return.</typeparam>
/// <param name="sql">The SQL to execute for this query.</param>
/// <param name="map">The function to map row types to the return type.</param>
/// <param name="param">The parameters to use for this query.</param>
/// <param name="transaction">The transaction to use for this query.</param>
/// <param name="buffered">Whether to buffer the results in memory.</param>
/// <param name="splitOn">The field we should split and read the second object from (default: "Id").</param>
/// <param name="commandTimeout">Number of seconds before command execution timeout.</param>
/// <returns>An enumerable of <typeparamref name="TReturn"/>.</returns>
public Task<IEnumerable<TReturn>> QueryAsync<TFirst, TSecond, TReturn>(string sql, Func<TFirst, TSecond, TReturn> 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);
/// <summary>
/// Perform an asynchronous multi-mapping query with 3 input types.
/// This returns a single type, combined from the raw types via <paramref name="map"/>.
/// </summary>
/// <typeparam name="TFirst">The first type in the recordset.</typeparam>
/// <typeparam name="TSecond">The second type in the recordset.</typeparam>
/// <typeparam name="TThird">The third type in the recordset.</typeparam>
/// <typeparam name="TReturn">The combined type to return.</typeparam>
/// <param name="sql">The SQL to execute for this query.</param>
/// <param name="map">The function to map row types to the return type.</param>
/// <param name="param">The parameters to use for this query.</param>
/// <param name="transaction">The transaction to use for this query.</param>
/// <param name="buffered">Whether to buffer the results in memory.</param>
/// <param name="splitOn">The field we should split and read the second object from (default: "Id").</param>
/// <param name="commandTimeout">Number of seconds before command execution timeout.</param>
/// <returns>An enumerable of <typeparamref name="TReturn"/>.</returns>
public Task<IEnumerable<TReturn>> QueryAsync<TFirst, TSecond, TThird, TReturn>(string sql, Func<TFirst, TSecond, TThird, TReturn> 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);
/// <summary>
/// Perform an asynchronous multi-mapping query with 4 input types.
/// This returns a single type, combined from the raw types via <paramref name="map"/>.
/// </summary>
/// <typeparam name="TFirst">The first type in the recordset.</typeparam>
/// <typeparam name="TSecond">The second type in the recordset.</typeparam>
/// <typeparam name="TThird">The third type in the recordset.</typeparam>
/// <typeparam name="TFourth">The fourth type in the recordset.</typeparam>
/// <typeparam name="TReturn">The combined type to return.</typeparam>
/// <param name="sql">The SQL to execute for this query.</param>
/// <param name="map">The function to map row types to the return type.</param>
/// <param name="param">The parameters to use for this query.</param>
/// <param name="transaction">The transaction to use for this query.</param>
/// <param name="buffered">Whether to buffer the results in memory.</param>
/// <param name="splitOn">The field we should split and read the second object from (default: "Id").</param>
/// <param name="commandTimeout">Number of seconds before command execution timeout.</param>
/// <returns>An enumerable of <typeparamref name="TReturn"/>.</returns>
public Task<IEnumerable<TReturn>> QueryAsync<TFirst, TSecond, TThird, TFourth, TReturn>(string sql, Func<TFirst, TSecond, TThird, TFourth, TReturn> 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);
/// <summary>
/// Perform an asynchronous multi-mapping query with 5 input types.
/// This returns a single type, combined from the raw types via <paramref name="map"/>.
/// </summary>
/// <typeparam name="TFirst">The first type in the recordset.</typeparam>
/// <typeparam name="TSecond">The second type in the recordset.</typeparam>
/// <typeparam name="TThird">The third type in the recordset.</typeparam>
/// <typeparam name="TFourth">The fourth type in the recordset.</typeparam>
/// <typeparam name="TFifth">The fifth type in the recordset.</typeparam>
/// <typeparam name="TReturn">The combined type to return.</typeparam>
/// <param name="sql">The SQL to execute for this query.</param>
/// <param name="map">The function to map row types to the return type.</param>
/// <param name="param">The parameters to use for this query.</param>
/// <param name="transaction">The transaction to use for this query.</param>
/// <param name="buffered">Whether to buffer the results in memory.</param>
/// <param name="splitOn">The field we should split and read the second object from (default: "Id").</param>
/// <param name="commandTimeout">Number of seconds before command execution timeout.</param>
/// <returns>An enumerable of <typeparamref name="TReturn"/>.</returns>
public Task<IEnumerable<TReturn>> QueryAsync<TFirst, TSecond, TThird, TFourth, TFifth, TReturn>(string sql, Func<TFirst, TSecond, TThird, TFourth, TFifth, TReturn> 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);
/// <summary>
/// Execute a query asynchronously using Task.
/// </summary>
/// <param name="sql">The SQL to execute.</param>
/// <param name="param">The parameters to use.</param>
/// <remarks>Note: each row can be accessed via "dynamic", or by casting to an IDictionary<string,object></remarks>
public Task<IEnumerable<dynamic>> QueryAsync(string sql, dynamic param = null) =>
_connection.QueryAsync(sql, param as object, _transaction);
/// <summary>
/// Execute a command that returns multiple result sets, and access each in turn.
/// </summary>
/// <param name="sql">The SQL to execute for this query.</param>
/// <param name="param">The parameters to use for this query.</param>
/// <param name="transaction">The transaction to use for this query.</param>
/// <param name="commandTimeout">Number of seconds before command execution timeout.</param>
/// <param name="commandType">Is it a stored proc or a batch?</param>
public Task<SqlMapper.GridReader> QueryMultipleAsync(string sql, dynamic param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null) =>
SqlMapper.QueryMultipleAsync(_connection, sql, param, transaction, commandTimeout, commandType);
}
}