Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/278.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# EF 6-如何正确执行并行查询_C#_.net_Sql Server_Entity Framework - Fatal编程技术网

C# EF 6-如何正确执行并行查询

C# EF 6-如何正确执行并行查询,c#,.net,sql-server,entity-framework,C#,.net,Sql Server,Entity Framework,创建报告时,我必须执行3个查询,这些查询涉及相同上下文中的独立实体。因为它们很重,我决定使用.ToListAsync()

创建报告时,我必须执行3个查询,这些查询涉及相同上下文中的独立实体。因为它们很重,我决定使用
.ToListAsync()
使用EF 6并行执行查询的正确方法是什么?我应该手动启动新任务吗

编辑1
代码基本上是

using(var MyCtx = new MyCtx())
{
      var r1 = MyCtx.E1.Where(bla bla bla).ToListAsync();
      var r2 = MyCtx.E2.Where(ble ble ble).ToListAsync();
      var r3 = MyCtx.E3.Where(ble ble ble).ToListAsync();
      Task.WhenAll(r1,r2,r3);
      DoSomething(r1.Result, r2.Result, r3.Result);
}
问题是:

EF不支持通过同一DbContext对象处理多个请求。如果在同一DbContext实例上的第二个异步请求在第一个请求完成之前启动(这就是关键所在),您将收到一条错误消息,表明您的请求正在针对开放的DataReader进行处理

资料来源:

您需要将代码修改为以下内容:

async Task<List<E1Entity>> GetE1Data()
{
    using(var MyCtx = new MyCtx())
    {
         return await MyCtx.E1.Where(bla bla bla).ToListAsync();
    }
}

async Task<List<E2Entity>> GetE2Data()
{
    using(var MyCtx = new MyCtx())
    {
         return await MyCtx.E2.Where(bla bla bla).ToListAsync();
    }
}

async Task DoSomething()
{
    var t1 = GetE1Data();
    var t2 = GetE2Data();
    await Task.WhenAll(t1,t2);
    DoSomething(t1.Result, t2.Result);
}
异步任务GetE1Data() { 使用(var MyCtx=new MyCtx()) { 返回等待MyCtx.E1.Where(blablabla.ToListAsync(); } } 异步任务GetE2Data() { 使用(var MyCtx=new MyCtx()) { 返回等待MyCtx.E2.Where(blablabla.ToListAsync(); } } 异步任务DoSomething() { var t1=GetE1Data(); var t2=GetE2Data(); 等待任务时(t1,t2); 剂量测定法(t1.结果,t2.结果); }
退房

从文件中:

SELECT语句和BULK INSERT语句的语句交错 允许。然而,数据操作语言(DML)和数据定义 语言(DDL)语句以原子方式执行


然后,您的上述代码就可以工作了,并且您可以获得读取数据的性能优势。

可能重复。一点提示。不要忘记在linq查询中调用AsNoQueryable。这将有助于提高性能您有什么例外?你能分享一些你如何并行执行查询的代码吗?@MiltonFilho“AsNoQueryable”?!?这听起来很可疑。。。谷歌对这种方法一无所知。。。这是一个框架吗?对不起,正确的是AsNoTracking。它会告诉EF不要观察所有对象的所有属性,并且会运行得很快。这样做是否有值得的性能提升?@Josh,这取决于它。如果多个调用(比方说10个调用)每个调用花费1秒,那么并行执行会导致总持续时间缩短,即按顺序运行时的10秒。但数据库引擎也有其局限性。如果你用并行请求轰炸它,它的资源消耗会增加。如果你想让加载的实体成为一个工作单元的一部分,并对它们进行更新,最后一起提交,那该怎么办?@mko你可能依赖于延迟加载,因此EF尝试加载其他数据,但由于上下文已被释放而失败。@binki:您可以将读取和写入分开:读取实体,将它们从上下文中分离。然后修改它们并将它们附加到单个上下文并保存更改。这并不能回答问题。