使用Entity Framework的多线程子查询会引发错误

时间:2011-05-19 16:07:40

标签: multithreading entity-framework iqueryable task-parallel-library objectcontext

我一直在尝试更新代码在数据库查询方面的性能。我目前遇到的问题是我似乎找不到为每个子查询获取新上下文的方法。

使用以下简化代码将不正确地生成“基础提供程序在打开时失败。”

using (var context = getNewContextObject())
{
    var result = new SomeResultObject();
    var parentQuery = context.SomeTable.Where(x => x.Name = "asdf");

    Parallel.Invoke(() =>
        {
            result.count1 = parentQuery.Where(x => x.Amount >= 100 & x.Amount < 2000).Count();
        }, () =>
        {
            result.count2 = parentQuery.Where(x => x.Amount < 100).Count();
        }
        , () =>
        {
            result.count3 = parentQuery.Where(x => x.Amount >= 2000).Count();
        }
    );

}

到目前为止,解决这个问题的唯一方法似乎是使用新的上下文重建每个子查询的整个查询。有没有办法避免使用新的Context自下而上构建每个查询?我可以将每个子查询查询附加到新上下文吗?我正在寻找类似下面的内容。

    Parallel.Invoke(() =>
        {
            var subQuery = parentQuery.Where(x => x.Amount >= 100 & x.Amount < 2000).Count();
            subQuery.Context = getNewContextObject();
            result.count1 = subQuery.Count();

        }, () =>
        {
            var subQuery = parentQuery.Where(x => x.Amount < 100).Count();
            subQuery.Context = getNewContextObject();
            result.count2 = subQuery.Count();
        }
        , () =>
        {
            var subQuery = parentQuery.Where(x => x.Amount >= 2000).Count();
            subQuery.Context = getNewContextObject();
            result.count3 = subQuery.Count();
        }
    );

}

1 个答案:

答案 0 :(得分:7)

我不确定这与您的问题究竟如何相关,但EF功能都不是线程安全的,所以我希望在同一个上下文实例上并行运行多个查询可能会因任何原因而爆炸。例如,他们在上下文中访问相同的连接属性,但线程彼此不知道,因此他们可以关闭与其他线程的连接或用其他连接实例替换实例(您可以尝试在并行运行之前手动打开连接线程并在完成所有线程后关闭它,但它不一定是唯一的问题。)