首页 > 解决方案 > Entity Framework 6 异步并行查询是否使用多个活动结果集进行连接池

问题描述

我有一些 EF 正在创建的非常大的查询,导致响应时间慢和 CPU 使用率高,所以我认为作为一种优化方法,我会尝试实现 MARS 和异步并行查询,以并行和操作拉回多个更简单的结果集在记忆中。

即我想这样做:

public async Task<IEnumerable<TResult>> GetResult<TResult>()
{
    using(var context = new Context())
    {
        return await context.Set<TResult1>().ToListAsync().ConfigureAwait(false);
    }
}

 
IEnumerable<TResult1> result1;
IEnumerable<TResult2> result2;

var result1Task = GetResult<TResult1>();
var result2Task = GetResult<TResult2>();

await Task.WhenAll(result1Task, result2Task).ConfigureAwait(false);

var result1 = result1Task.Result;
var result2 = result2Task.Result;

但不确定这是否利用了连接池,因为它DBContext为每个任务创建了一个新的。

我找到了这篇文章,但它没有使用实体框架。

我发现这个是使用 Core 的,这不是推荐的策略。

这个使用 .NET 框架的实体框架,但使用存储过程作为示例,但我只想并行发出 3 个读取查询,而不是调用 SP。

理想情况下,寻找一种方法来实现多个结果集,使用 linq 生成 SQL(与使用字符串相比select Id, VendorName From Vendors....)并将结果自动映射到类,而无需使用字符串(vendorID = (int)vendorReader["BusinessEntityID"];)。

这是可能的还是白日梦?

标签: entity-frameworkasynchronousentity-framework-6sql-server-mars

解决方案


在应用程序中具有并行性的 ORM 通常无法解决同时运行多个查询的要求。从多个线程访问单个 DbContext 是不安全的。相反,使用了一种称为未来查询的模式。对于 EF6,这在第三方库https://www.nuget.org/packages/Z.EntityFramework.Plus.EF6/中可用

API 非常简单,由一个扩展方法组成,该方法将导致查询被添加到内部列表,直到其中一个查询被具体化(例如,通过调用 ToList)。此时,所有的查询都被一次性发送到服务器,结果也一起返回。


推荐阅读