更新
我从this question找到EnsureOpen
,使我的主搜索不是异步,因为以下两种方法依赖它。我仍然会欣赏这方面的建议,但似乎确实有效。
问题
我正在使用Dapper与EF6一起进行一些需要快速查询并在负载测试中遇到连接关闭问题的查询。我通过传递DbContext并使用它的连接来解决这个问题,这是一个WepApi控制器,我使用Ninject来创建上下文。
现在我想要异步所有,我收到连接关闭的错误。当我尝试打开连接时,我似乎没有正确关闭它。当我将它包装在一个使用块中并创建一个新连接时,我得到了
: Timeout expired. The timeout period elapsed prior to obtaining a connection from the pool. This may have occurred because all pooled connections were in use and max pool size was reached.
我目前的简化代码是:
public class TestController : ApiController
{
private readonly TestEntities _context;
public TestController(TestEntities context)
{
_context = context;
}
public async Task<IEnumberable<TestViewModel>> Get()
{
var main = new MainSearch();
var mainData = async main.GetMainDataAsync(_context);
var ids = mainData.Select(o => o.Id).ToArray();
var extras1 = new Extras1();
var extras1Data = async extras1.GetExtras1Async();
var extras2 = new Extras2();
var extras2Data = async extras2.GetExtras2Async();
foreach(var data in mainData)
{
mainData.Extras1 = extras1[data.Id];
mainData.Extras2 = extras2[data.Id];
}
return mainData;
}
}
public class MainSearch
{
public async Task<List<MainViewModel>> GetMainDataAsync(TestEntities context)
{
using (var connection = new SqlConnection(context.Database.Connection.ConnectionString))
{
await connection.OpenAsync();
var builder = new SqlBuilder();
var query = builder.AddTemplate("SELECT Id FROM Main");
//removed filter and sorting for SO question
return await connection.QueryAsync<MainViewModel>(query.RawSql, param: query.Parameters);
}
}
public class Extras1
{
public async Task<List<Extra1ViewModel>> GetExtras1Async(TestEntities context, int[] ids)
{
using (var connection = new SqlConnection(context.Database.Connection.ConnectionString))
{
await connection.OpenAsync();
var result = connection.Query<Extra1ViewModel>("SELECT * FROM Extras1 WHERE ID IN @Ids", new {Ids = ids});
return result.ToLookup(o => o.MainId);
}
}
public class Extras2
{
public async Task<List<Extra2ViewModel>> GetExtras1Async(TestEntities context, int[] ids)
{
using (var connection = new SqlConnection(context.Database.Connection.ConnectionString))
{
await connection.OpenAsync();
var result = connection.Query<Extra1ViewModel>("SELECT * FROM Extras2 WHERE ID IN @Ids", new {Ids = ids});
return result.ToLookup(o => o.MainId);
}
}