为IDBCommand与SqlCommand.ExecuteNonQueryAsync实现异步ExecuteNonQuery()

时间:2019-04-29 14:27:41

标签: c# async-await ado.net task-parallel-library

我将IDBCommand用于我的数据库层,以便切换到SqlDataProvider以外的其他数据库提供程序。

SqlCommand具有所有Execute方法,例如ExecuteNonQueryAsync,但IDBCommand不包含异步方法。

将来,我们可能需要切换到Sql以外的其他数据提供者,我只是不能直接使用SqlCommand

我只是想实现自己的异步版本。如果实现自己的性能,会不会有性能方面的顾虑?还是最好使用Microsoft实现的SqlCommand对象可用的异步方法?

通过以下方式,我实现了Async方法。以下是同步:

public int ExecuteNonQuery(CommandType commandType, string commandText)
{
    PrepareCommand(commandType, commandText);
    var noOFRowsAffected = _dbCommand.ExecuteNonQuery();
    SetParameters(_dbCommand.Parameters);
    return noOFRowsAffected;
 }

以下是Async版本:

public async Task<int> ExecuteNonQueryAsync(CommandType commandType, string commandText)
{
    PrepareCommand(commandType, commandText);

    var noOFRowsAffected = await Task.Factory.StartNew(() =>
    {
        return _dbCommand.ExecuteNonQuery();
    });

    SetParameters(_dbCommand.Parameters);
    return noOFRowsAffected;
}
  

请注意,异常处理将由调用处理   层。

谁能给我正确的方向?这是执行异步操作的正确方法,还是我应该使用Microsoft实现的SqlCommand来使用其自己的方法?任何帮助都非常感谢。在此先感谢:)

3 个答案:

答案 0 :(得分:2)

请注意,尽管您可以利用数据提供程序来创建对象,但是仍然需要考虑每个提供程序在SQL中的差异。

如果您确实希望代码不可知,那么最好使用Entity Framework,NHitbertate或任何其他ORM。

永远不要将Task.Factory.StartNewasync-await一起使用。请改用Task.Run。但是对于异步而不是同步来说,这不是一个好习惯。

如果您使用DbCommand而不是IDbCommand,那么您已经拥有ExecuteNonQueryAsync

答案 1 :(得分:1)

我建议您使用Dapper。无需编写所有样板ADO.NET代码,也不必担心是否可以更改提供程序。它还支持全面的异步操作。

  

Dapper没有特定于数据库的实现细节,它适用于所有   .NET ADO提供程序,包括SQLite,SQL CE,Firebird,Oracle,MySQL,   PostgreSQL和SQL Server。

教程

https://dapper-tutorial.net/async

答案 2 :(得分:1)

您可以在System.Data.Common名称空间中使用抽象类。他们确实有异步方法。例如:

DbCommand.ExecuteNonQueryAsync()

System.Data.SqlClient.SqlCommand继承自该基类,希望其他数据提供者也这样做。