我一直在构建我的数据访问层,性能是我正在进行的项目的关键。
我选择使用Dapper和dotnet 3,我想利用dotnet和Dapper中最新和最伟大的异步特性,以便在负载较重的情况下进行更智能的资源分配,但是没有太多的文档。
所有的dapper似乎都使用非异步,我为SqlConnection
找到的大多数示例都使用非异步方法。
我想知道是否所有异步和等待的使用是值得的开销。
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Threading.Tasks;
using Dapper;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Outible.API.Model;
using Outible.DataAccess.Interfaces;
namespace Outible.DataAccess.Models
{
public class Db : IDb
{
private readonly IOptionsMonitor<ConnectionStrings> _connectionStrings;
private readonly ILogger<Db> _logger;
public Db(IOptionsMonitor<ConnectionStrings> connectionStrings, ILogger<Db> logger)
{
_connectionStrings = connectionStrings;
_logger = logger;
}
private async Task<T> CommandAsync<T>(Func<IDbConnection, IDbTransaction, int, Task<T>> command)
{
var connection = new SqlConnection(_connectionStrings.CurrentValue.MainDatabase);
await connection.OpenAsync().ConfigureAwait(false);
await using var transaction = await connection.BeginTransactionAsync();
try
{
var result = await command(connection, transaction, 300).ConfigureAwait(false);
await transaction.CommitAsync().ConfigureAwait(false);
return result;
}
catch (Exception ex)
{
await transaction.RollbackAsync().ConfigureAwait(false);
_logger.LogError(ex, "Rolled back transaction");
throw;
}
}
public Task<int> ExecuteAsync(string sql, object parameters)
{
return CommandAsync((conn, trn, timeout) => conn.ExecuteAsync(sql, parameters, trn, timeout));
}
public Task<T> GetAsync<T>(string sql, object parameters)
{
return CommandAsync((conn, trn, timeout) => conn.QuerySingleOrDefaultAsync<T>(sql, parameters, trn, timeout));
}
public Task<IEnumerable<T>> SelectAsync<T>(string sql, object parameters)
{
return CommandAsync((conn, trn, timeout) => conn.QueryAsync<T>(sql, parameters, trn, timeout));
}
}
}
发布于 2019-11-05 01:00:35
我看到您已经将using
应用于事务。
但是,考虑到为每个命令创建了一个新的SqlConnection
,我建议将其封装在using
语句中。
private async Task<T> CommandAsync<T>(Func<IDbConnection, IDbTransaction, int, Task<T>> command)
{
using(var connection = new SqlConnection(_connectionStrings.CurrentValue.MainDatabase))
{
await connection.OpenAsync().ConfigureAwait(false);
await using var transaction = await connection.BeginTransactionAsync();
try
{
T result = await command(connection, transaction, 300).ConfigureAwait(false);
await transaction.CommitAsync().ConfigureAwait(false);
return result;
}
catch (Exception ex)
{
await transaction.RollbackAsync().ConfigureAwait(false);
_logger.LogError(ex, "Rolled back transaction");
throw;
}
}
}
https://codereview.stackexchange.com/questions/231856
复制相似问题