C# in Parallel.ForEach:基础提供程序在打开时失败。使用EF5

C# in Parallel.ForEach:基础提供程序在打开时失败。使用EF5,c#,entity-framework-5,C#,Entity Framework 5,此代码有时对某些项目有效,但在尝试处理更多项目时总是失败,我会得到以下结果:{“基础提供程序在打开时失败”。}异常 List<Recon> scenarioAll = db.Transactions .Where(t => t.SrcObjTyp == "13") .Select(t => t.Recon).ToList(); //db.Transactions.Where(t =>

此代码有时对某些项目有效,但在尝试处理更多项目时总是失败,我会得到以下结果:
{“基础提供程序在打开时失败”。}
异常

  List<Recon> scenarioAll = db.Transactions
                  .Where(t => t.SrcObjTyp == "13")
                  .Select(t => t.Recon).ToList();


  //db.Transactions.Where(t => t.SrcObjTyp == "13").ToList().ForEach(t => reconsWithType13Trans.Add(t.Recon));

  Parallel.ForEach(scenarioAll.Take(100), r =>
  {

    // ### Exception : {"The underlying provider failed on Open."} here ###
    invoices = r.Transactions.SelectMany(t => t.InvoiceDetails).ToList();


    CreateFacts(invoices, r/*, db*/).ForEach(f => facts.Add(f));
    transactions = r.Transactions.Where(t => !t.SrcObjTyp.Contains("13")).ToList();
    DistributeTransactionOnItemCode(transactions, facts);
    Console.WriteLine(i += 1);
  });

  facts.ForEach(f => db.ReconFacts.Add(f));
  db.SaveChanges();
List scenarioAll=db.Transactions
.其中(t=>t.SrcObjTyp==“13”)
.Select(t=>t.Recon.ToList();
//其中(t=>t.SrcObjTyp==“13”).ToList().ForEach(t=>reconsWithType13Trans.Add(t.Recon));
Parallel.ForEach(scenarioAll.Take(100),r=>
{
//####异常:{“基础提供程序在打开时失败。”}此处###
发票=r.Transactions.SelectMany(t=>t.InvoiceDetails.ToList();
CreateFacts(invoices,r/*,db*/).ForEach(f=>facts.Add(f));
transactions=r.transactions.Where(t=>!t.SrcObjTyp.Contains(“13”)).ToList();
DistributeTransactionOnItemCode(事务、事实);
控制台写入线(i+=1);
});
facts.ForEach(f=>db.ReconFacts.Add(f));
db.SaveChanges();
我认为issus是多进程同时访问数据库,是否可以通过这种方式允许多进程查询EF

还有一种方法可以加载内存中的所有内容,以便在访问
Recon
的子级时,像这样
r.Transactions.SelectMany(t=>t.InvoiceDetails.ToList()所有内容都在内存中,而不访问底层数据库


我应该使用什么解决方案?你认为什么是最好的

您的问题是有多个线程试图延迟加载。 尝试将加载查询替换为

List<Recon> scenarioAll = db.Transactions
              .Where(t => t.SrcObjTyp == "13")
              .Select(t => t.Recon)
              .Include(r => r.Transactions.Select(t => t.InvoiceDetails))
              .ToList();

看起来是个不错的回答谢谢。但现在我得到一个“超时过期”异常。。。你知道我该如何管理它吗?你可以看看生成的SQL并尝试添加索引来修复它。但最终,您将带回的数据集要大得多。尝试找出这是带宽(不可调整)问题还是延迟问题(您可以优化查询)。PS您的
.Take(100)
应该在
.ToList()之前。
…您现在所做的就是取出整个数据库,然后在前100个数据库上迭代。。。你真的只想向数据库请求100行。你是对的,我想出来并更改了它。谢谢
 var query =  = db.Transactions
              .Where(t => t.SrcObjTyp == "13")
              .Select(t => t.Recon);
 var scenarioAll = query.ToList();
 var invoicesByReconIdQuery = from r in query
                              from t in r.Transactions
                              from i in t.InvoiceDetails
                              group i by r.Id into g
                              select new { Id = g.Key, Invoices = g.ToList() };


 var invoicesByReconId = invoicesByReconIdQuery.ToDictionary(x => x.Id, x => x.Invoices);

 Parallel.ForEach(scenarioAll.Take(100), r =>
 {

     // ### Exception : {"The underlying provider failed on Open."} here ###
     var invoices = invoicesByReconId[r.Id];
 }