C# 实体框架“;意外连接状态“;例外情况

C# 实体框架“;意外连接状态“;例外情况,c#,entity-framework,signalr,C#,Entity Framework,Signalr,经过三个小时的调试和搜索,我希望这里有人能给出答案。如果我连续快速调用以下函数(例如相隔x.MaterialId.ToList(); //从数据库中删除旧材料 var oldMaterials=Db.Materials.Where(p=>p.CreatedBy==id&& MaterialId.Contains(p.MaterialId)).ToList();//异常 Db.Materials.Removate(旧材料); Db.SaveChanges(); //用列表中的新材料替换以前的材料

经过三个小时的调试和搜索,我希望这里有人能给出答案。如果我连续快速调用以下函数(例如相隔<0.1秒),Entity Framework(使用MySQL)会引发以下异常

System.InvalidOperationException:意外的连接状态。使用包装提供程序时,请确保在包装的DbConnection上实现StateChange事件

但是,有时该函数工作时没有任何问题。在第一次调用
ToList()
时引发异常:

void InsertOrUpdateMaterials(List<Material> materials)
{
    var id = GetUserId();
    var materialIds = materials.Select(x => x.MaterialId).ToList();

    // Remove old materials from DB
    var oldMaterials = Db.Materials.Where(p => p.CreatedBy == id && 
            materialIds.Contains(p.MaterialId)).ToList(); // exception
    Db.Materials.RemoveRange(oldMaterials);
    Db.SaveChanges();

    // Replace previous materials with the new ones in list
    Db.Materials.AddRange(materials);
    Db.SaveChanges();
}
void InsertOrUpdateMaterials(列出材料)
{
var id=GetUserId();
var MaterialId=materials.Select(x=>x.MaterialId.ToList();
//从数据库中删除旧材料
var oldMaterials=Db.Materials.Where(p=>p.CreatedBy==id&&
MaterialId.Contains(p.MaterialId)).ToList();//异常
Db.Materials.Removate(旧材料);
Db.SaveChanges();
//用列表中的新材料替换以前的材料
Db.Materials.AddRange(物料);
Db.SaveChanges();
}
奇怪的是,这个错误从未在开发服务器上发生过,所以我研究了可能的配置问题,但没有结果

有时,实体框架抛出:

System.Data.Entity.Core.EntityCommandExecutionException:已存在与此连接关联的打开的DataReader,必须先关闭该DataReader


再次指向
ToList()
调用。有什么想法吗?

给其他可能有类似问题的人。根据上面的注释,代码似乎使用了缓存的db上下文。创建db上下文后,db连接断开(应用程序中未安装任何
StateChange
处理程序)。连接中断后,应用程序使用缓存的db上下文对其执行一些操作


创建一个新的数据库上下文解决了这个问题。

我在
努力中遇到了这个问题。EF6
1.3.0。我的解决办法是将
NMemory
依赖项从1.1.0更新到1.1.2。

我在使用
努力时遇到了同样的问题。EF6
,但是更新
NMemory
(如建议的那样)没有帮助。结果是

禁用此行为为我修复了它。将以下内容添加到AssemblyInfo.cs:

using Xunit;
[assembly: CollectionBehavior(CollectionBehavior.CollectionPerAssembly)]

尽管我认为这是一种解决方法,但单元测试应该相互独立。

请注意不要在其他线程中使用DbContext,只在UI线程中使用它。
如果需要从其他线程调用包含DbContext的函数, 您需要通过
SynchronizationContext
类调用它


我认为DbContext不能在每个线程UI和其他线程UI的同时使用。

了解
Db
的来源会很有帮助。我的猜测是,这确实是在说实话——在打开数据库上的初始连接和执行
ToList
(这里出现异常,因为这是当查询针对数据库“具体化”时)之间,连接的状态已更改(关闭等)。EF暗示您应该处理
StateChange
以处理此问题(例如重新打开连接或其他任何问题)。您的评论帮助我找到了解决方案!谢谢你,先生!!我查看了
Db
的来源,并缓存了上下文。我让它每次初始化一个新的上下文,问题就解决了。真让人惊讶,我竟然漏掉了这一条。@arao6想写一个更详细的答案吗?仅供参考,您可以在StackOverflow中为自己的问题写一个答案。而且,FWIW,我可能会投票:)请有人写一个更详细的答案。确保在使用(var DB=new DbContext()){…use…}时创建一个新的DB上下文。你是否看到了与之相同的并行化问题?我不确定,我使用的是NUnit 3.7。我修复了我的问题,按照@Stephen Byrne的建议更改了DbContext的处理方式。为什么在单元测试中使用真实数据库。模拟一下,这样速度会更快。