我在调用 Entity Framework 时遇到了一些奇怪的错误,我正在探索它们是否可能是由于使用相同的 ObjectContext
进行并发多线程访问造成的。
我试图通过将创建上下文放入 ThreadLocal 来为每个线程创建一个新的上下文。
private System.Threading.ThreadLocal<EF.XYZEntities> threadLocalContext = new System.Threading.ThreadLocal<EF.XYZEntities>(() => new EF.XYZEntities(connectionString));
private EF.XYZEntities context { get { return threadLocalContext.Value; } }
这是行不通的。第一次使用该上下文会引发错误:
Invalid object name 'dbo.Site'.
我怎样才能让它工作?
最佳答案
使用共享上下文通常被认为是“不好的”,除非您很好地微观管理一切。使用管理不善的共享上下文会产生非常奇怪的结果。
通常最佳做法是在上下文中采用工作单元方法,如下所示:
using (DBEntities ctx = new DBEntities())
{
// Explicitly open the context connection yourself - to help prevent connection pooling / sharing
// The connection will automatically be closed once exiting the using statement,
// but it won't hurt to put a ctx.Connection.Close(); after everything inside the using statement.
ctx.Connection.Open();
// Do Stuff
// If necessary ctx.SaveChanges();
// Not necessary but you could put a ctx.Connection.Close() here, for readability if nothing else.
}
更新:回复 Noseratio 下面关于异步和 EF 的评论。 Taken from here
非目标
以下是我们明确不尝试使用 EF6 中的功能启用的内容:
- 线程安全
- 异步延迟加载
线程安全
虽然线程安全会使异步更有用,但它是一个正交特性。鉴于 EF 与由用户代码组成的图形交互以维护状态,并且没有简单的方法来确保此代码也是线程安全的,因此目前尚不清楚我们能否在最一般的情况下实现对它的支持。
目前,EF 将检测开发人员是否试图同时执行两个异步操作并抛出....
EF 中的异步支持需要 .NET 4.5,并且在 .NET 4 上不可用。
关于c# - 创建 ThreadLocal EF 上下文,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21306626/