异步填充C#数据表
我正在向WebAPI项目中使用的所有SQL基类添加异步实现。我对TAP范式相当陌生,所以我还在学习 我知道,多亏了其他文章,通过Task.Run()生成线程在ASP.NET环境中没有任何性能优势。所以我对我的实现格外小心 我已将我的QueryExecutor方法更改为下面的异步实现。但无法确定加载数据表的最佳方式是什么。我想我最好使用异步填充C#数据表,c#,.net,sql-server,datatable,async-await,C#,.net,Sql Server,Datatable,Async Await,我正在向WebAPI项目中使用的所有SQL基类添加异步实现。我对TAP范式相当陌生,所以我还在学习 我知道,多亏了其他文章,通过Task.Run()生成线程在ASP.NET环境中没有任何性能优势。所以我对我的实现格外小心 我已将我的QueryExecutor方法更改为下面的异步实现。但无法确定加载数据表的最佳方式是什么。我想我最好使用reader.ReadAsync()来填充数据表,但在.NET4.5框架中似乎没有任何可用的工具 所以我想问,是否值得编写自己的扩展方法,比如DataTable.L
reader.ReadAsync()
来填充数据表,但在.NET4.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;
}
}
}
专用异步任务ExecuteQueryInternalAsync(字符串commandText、CommandType CommandType、SqlConnection SqlConnection、SqlTransaction transaction、params SqlParameter[]参数)
{
使用(SqlCommand cmd=newsqlcommand(commandText,sqlConnection){CommandType=CommandType,CommandTimeout=this.config.mainconnectiontimeoutineseconds})
{
if(事务!=null)
cmd.Transaction=Transaction;
if(参数!=null)
{
foreach(参数中的var参数)
{
if(参数!=null)
{
if(parameter.Value==null)
parameter.Value=DBNull.Value;
cmd.Parameters.Add(参数);
}
}
}
if(sqlConnection.State==ConnectionState.Closed)
等待sqlConnection.OpenAsync();
使用(var reader=await cmd.ExecuteReaderAsync())
{
//要使用:reader.ReadAsync()
var tb=新数据表();
tb.Load(读卡器);
返回结核病;
}
}
}
谢谢如果需要扩展方法,可以直接在命令上编写
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;
}
}
公共静态类扩展
{
公共异步静态任务ExecuteAndCreateDataTableAsync(此SqlCommand cmd)
{
使用(var reader=await cmd.ExecuteReaderAsync().ConfigureAwait(false))
{
var dataTable=reader.CreateTableSchema();
while(wait reader.ReadAsync().configurewait(false))
{
var dataRow=dataTable.NewRow();
对于(int i=0;i
还有你的方法:
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;
}
}
专用异步任务ExecuteQueryInternalAsync(字符串commandText、CommandType CommandType、SqlConnection SqlConnection、SqlTransaction transaction、params SqlParameter[]参数)
{
使用(SqlCommand cmd=newsqlcommand(commandText,sqlConnection){CommandType=CommandType,CommandTimeout=this.config.mainconnectiontimeoutineseconds})
{
if(事务!=null)
cmd.Transaction=Transaction;
cmd.LoadParams(参数);
if(sqlConnection.State==ConnectionState.Closed)
等待sqlConnection.OpenAsync();
var datatable=await cmd.ExecuteAndCreateDataTableAsync();
返回数据表;
}
}
只是一个侧节点:示例代码由.Net代码管理。通常,异步代码使用实体框架查询,而不是DataTable
s。我确实使用EF 6。但有时您只需要执行一个SP并将结果作为一个数据表来获取,所以我的部分问题是,这样做值得吗?是否值得使用ReadAsync()而不仅仅是同步填充数据表。这只是实现。我认为在ExecuteReaderAsync之后是没有必要的