实体框架懒惰加载不能从其他线程工作 [英] Entity Framework lazy loading doesn't work from other thread

查看:88
本文介绍了实体框架懒惰加载不能从其他线程工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚刚发现,实体框架中的延迟加载只能从创建 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆