【发布时间】:2021-05-18 23:13:07
【问题描述】:
我有一些 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。
我找到了this article,但它没有使用实体框架。
我发现 this one 使用 Core,这不是推荐的策略。
而this one 使用 Entity Framework for .NET 框架,但使用存储过程作为示例,但我只想并行发出 3 个读取查询,而不是调用 SP。
理想情况下,寻找一种方法来实现多个结果集,使用 linq 生成 SQL(与使用字符串 select Id, VendorName From Vendors.... 相比)并将结果自动映射到类而无需使用字符串 (vendorID = (int)vendorReader["BusinessEntityID"];)。
这是可能的还是白日梦?
【问题讨论】:
-
这一切都相当广泛和不清楚。尝试将范围缩小到一个有一个明确问题的示例。
-
@GertArnold 就我的问题添加了更多细节。
-
你混淆了各种概念。现在您向它们添加连接池。 MARS != 池化,MARS != 多个结果集(是的,真的),MARS != 并行编程。为什么不直接将选定的实体连续加载到上下文中并让关系修复来完成这项工作?可能比任何并行数据库访问都要快,然后手动映射。
-
@GertArnold 我敢肯定,因为我对这些并不太熟悉并寻求帮助。我想要最高效的方式来执行多个查询并通过利用任何和所有方式解析为
list<class>。连接池、MARS、异步等。如果您知道或对您认为最高效的方法有任何建议,我很乐意看到对此效果的答案。我不确定您所说的“让关系修复完成工作”是什么意思。我不确定您所说的“并行映射后手动映射”是什么意思?为什么会是手动的?在我的示例中,它们映射到TRESULT。 -
我不能比你少含糊。作为第一次尝试将所有数据按顺序加载到一个上下文中,您会看到 EF 填充了所有引用和集合。 IE。尝试在 EF 核心中模拟 split queries。
标签: entity-framework asynchronous entity-framework-6 sql-server-mars