实体框架懒惰加载不能从其他线程工作 [英] Entity Framework lazy loading doesn't work from other thread
问题描述
ObjectContext
的线程工作。为了说明问题,我做了一个简单的测试,一个简单的模型只包含两个实体: Person
和 Address
。以下是代码: private static void TestSingleThread()
{
using(var context = new TestDBContext ())
{
foreach(var p in context.Person)
{
Console.WriteLine({0}住在{1},p.Name, p.Address.City);
}
}
}
private static void TestMultiThread()
{
using(var context = new TestDBContext())
{
foreach(var p in context.Person)
{
Person p2 = p; //以避免捕获循环变量
ThreadPool.QueueUserWorkItem(
arg =>
{
Console.WriteLine({0}住在{1},p2 .Name,p2.Address.City);
});
}
}
}
TestSingleThread
方法工作正常,地址
属性被延迟加载。但是在 TestMultiThread
中,我得到一个 NullReferenceException
在 p2.Address.City
,因为 p2.Address
为null。
这是一个bug?这是应该工作的方式吗?如果是这样,有没有提到的文件?我在MSDN或Google上找不到任何内容。
更重要的是,是否有解决方法? (除了从工作线程显式调用 LoadProperty
...)
任何帮助将非常感谢
PS:我使用的是VS2010,所以是EF 4.0。我不知道在以前版本的EF中是否一样。
这是按设计吗?是;任何调用Load(隐式或者显式)的调用最终都将通过 ObjectContext
和 ObjectContext被记录为不是线程安全的。
可能的解决方法要将实体与工作线程中的对象上下文分离,并将其附加到当前线程中的对象上下文中。
I just found out that lazy loading in Entity Framework only works from the thread that created the ObjectContext
. To illustrate the problem, I did a simple test, with a simple model containing just 2 entities : Person
and Address
. Here's the code :
private static void TestSingleThread()
{
using (var context = new TestDBContext())
{
foreach (var p in context.Person)
{
Console.WriteLine("{0} lives in {1}.", p.Name, p.Address.City);
}
}
}
private static void TestMultiThread()
{
using (var context = new TestDBContext())
{
foreach (var p in context.Person)
{
Person p2 = p; // to avoid capturing the loop variable
ThreadPool.QueueUserWorkItem(
arg =>
{
Console.WriteLine("{0} lives in {1}.", p2.Name, p2.Address.City);
});
}
}
}
The TestSingleThread
method works fine, the Address
property is lazily loaded. But in TestMultiThread
, I get a NullReferenceException
on p2.Address.City
, because p2.Address
is null.
It that a bug ? Is this the way it's supposed to work ? If so, is there any documentation mentioning it ? I couldn't find anything on the subject on MSDN or Google...
And more importantly, is there a workaround ? (other than explicitly calling LoadProperty
from the worker thread...)
Any help would be very appreciated
PS: I'm using VS2010, so it's EF 4.0. I don't know if it was the same in the previous version of EF...
Is this by design? Yes; any call to Load, implicit or explicit, will eventually go through the ObjectContext
, and ObjectContext is documented to be not thread-safe.
A possible workaround would be to detach the entity from the object context in the worker thread and attach it to an object context in the current thread.
这篇关于实体框架懒惰加载不能从其他线程工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!