我正在向我的WebAPI项目中使用的所有SQL基类添加异步实现。我对TAP范例很新,所以我还在学习。
我知道,感谢其他帖子,通过Task.Run()生成一个线程在ASP.NET上下文中没有任何性能优势。所以我对我的实现要格外小心。
我已将 QueryExecutor 方法更改为下面的异步实现。但无法弄清楚加载 DataTable 的最佳方法是什么。我猜我最好想用reader.ReadAsync()
来填充DataTable,但似乎.NET 4.5框架中没有任何可用的东西。
所以我想问一下是否值得编写我自己的扩展方法,例如DataTable.LoadAsync(DbDataReader reader)
?我有点不想,如果它可以得到帮助,因为它不会像托管的.Net代码那样简单。
让我知道你们的想法。
private async Task<DataTable> ExecuteQueryInternalAsync(string commandText, CommandType commandType, SqlConnection sqlConnection, SqlTransaction transaction, params SqlParameter[] parameters)
{
using (SqlCommand cmd = new SqlCommand(commandText, sqlConnection) { CommandType = commandType, CommandTimeout = this.config.MainConnectionTimeoutInSeconds })
{
if (transaction != null)
cmd.Transaction = transaction;
if (parameters != null)
{
foreach (var parameter in parameters)
{
if (parameter != null)
{
if (parameter.Value == null)
parameter.Value = DBNull.Value;
cmd.Parameters.Add(parameter);
}
}
}
if (sqlConnection.State == ConnectionState.Closed)
await sqlConnection.OpenAsync();
using (var reader = await cmd.ExecuteReaderAsync())
{
//Want to use: reader.ReadAsync()
var tb = new DataTable();
tb.Load(reader);
return tb;
}
}
}
由于
答案 0 :(得分:2)
如果您想要扩展方法,可以直接在命令
上书写public static class extensions
{
public async static Task<DataTable> ExecuteAndCreateDataTableAsync(this SqlCommand cmd)
{
using (var reader = await cmd.ExecuteReaderAsync().ConfigureAwait(false))
{
var dataTable = reader.CreateTableSchema();
while (await reader.ReadAsync().ConfigureAwait(false))
{
var dataRow = dataTable.NewRow();
for (int i = 0; i < dataTable.Columns.Count; i++)
{
dataRow[i] = reader[i];
}
dataTable.Rows.Add(dataRow);
}
return dataTable;
}
}
public static void LoadParams(this SqlCommand cmd, params SqlParameter[] parameters)
{
if (parameters != null)
{
foreach (var parameter in parameters)
{
if (parameter != null)
{
if (parameter.Value == null)
parameter.Value = DBNull.Value;
cmd.Parameters.Add(parameter);
}
}
}
}
private static DataTable CreateTableSchema(this SqlDataReader reader)
{
DataTable schema = reader.GetSchemaTable();
DataTable dataTable = new DataTable();
if (schema != null)
{
foreach (DataRow drow in schema.Rows)
{
string columnName = System.Convert.ToString(drow["ColumnName"]);
DataColumn column = new DataColumn(columnName, (Type)(drow["DataType"]));
dataTable.Columns.Add(column);
}
}
return dataTable;
}
}
和你的媒体:
private async Task<DataTable> ExecuteQueryInternalAsync(string commandText, CommandType commandType, SqlConnection sqlConnection, SqlTransaction transaction, params SqlParameter[] parameters)
{
using (SqlCommand cmd = new SqlCommand(commandText, sqlConnection) { CommandType = commandType, CommandTimeout = this.config.MainConnectionTimeoutInSeconds })
{
if (transaction != null)
cmd.Transaction = transaction;
cmd.LoadParams(parameters);
if (sqlConnection.State == ConnectionState.Closed)
await sqlConnection.OpenAsync();
var datatable = await cmd.ExecuteAndCreateDataTableAsync();
return datatable;
}
}