具有实体框架的具有多个线程的单一上下文
Posted
技术标签:
【中文标题】具有实体框架的具有多个线程的单一上下文【英文标题】:Single context with many threads with Entity Framework 【发布时间】:2014-12-31 18:54:59 【问题描述】:我有以下:
await Task.WhenAll(
Task.Run(() => HandleJob("one"),
Task.Run(() => HandleJob("two"),
Task.Run(() => HandleJob("three"));
HandleJob 在哪里:
private async Task HandleJob(string param)
using (var db = new DbContext())
_numberService = new NumberService(db);
_numberService.DoThis(param);
而 NumberService 是这样的:
public class NumberService
private readonly DbContext db;
private CommService _commService;
public NumberService(DbContext db)
this.db = db;
_commService = new CommService(db);
public void DoThis(string param)
_commService.DoThat(param);
CommService 是这样的:
public class CommService
private readonly DbContext db;
public CommService(DbContext db)
this.db = db;
public void DoThat(string param)
db.Things.Add(param);
db.SaveChanges();
我遇到了一个问题,当我尝试运行它时看到以下内容:
System.InvalidOperationException 类型的异常 发生在 EntityFramework.dll 但未在用户代码中处理 上下文 在创建模型时不能使用。这个例外可能是 如果在 OnModelCreating 方法中使用了上下文,或者如果 同一个上下文实例被多个线程访问 同时。请注意,DbContext 和相关的实例成员 不保证类是线程安全的。
我做错了什么?我认为通过为每个线程使用一个新的dbContext
,我会没事的。
【问题讨论】:
对我来说似乎很好。我以前见过这个错误;它基本上可以表示各种各样的东西。在发生这种情况的地方发布整个调用堆栈。在 await 关键字之前试试这个:using (var dbCOntext = new DbContext()) dbCOntext.Database.Initialize(force: false);
这可能不是线程问题,您可能在该新上下文中执行代码,而该上下文尚不存在或仍在创建中。
db.Things.Add(param);是错误的,因为 param 是一个字符串,而不是 Thing 的实例。然后它继续抛出一个没有处理的异常
@TienDinh 这只是一个语法错误 - 我在这里简化代码。
回头看你的代码,我可以看到很多语法错误。我怀疑您的问题代码是否包含在内。
【参考方案1】:
我是个白痴。这是因为我在 async 方法之外定义了_numberService
,所以每次异步使用都为其他使用重写了上下文。多哈。
【讨论】:
以上是关于具有实体框架的具有多个线程的单一上下文的主要内容,如果未能解决你的问题,请参考以下文章
无法生成显式迁移 - 具有多个上下文/配置的实体框架 6.1.3
如何在具有存储库模式的实体框架中伪造 DbContext.Entry 方法
将 DbContext 拆分为具有重叠 DbSet 的多个上下文