更改IQueryable的DataContext

时间:2015-06-08 10:04:10

标签: c# multithreading linq-to-sql task-parallel-library datacontext

我正在开发一个使用静态全局DataContext的项目(不建议这样做,但此时很难改变)。我目前需要通过并行化一些独立的函数来提高某些部分的性能。由于DataContext不是线程安全的,我不能在新创建的线程中使用它。因此,我在每个线程中创建了一个新的DataContext,并将其放置在线程的末尾。

使用新的datacontext,一切顺利,但我遇到的问题是函数的一个输入是附加到Global DataContext的IQueryable。运行该方法将导致"例外,已经有一个与此命令关联的打开的DataReader必须先关闭。"

问题是,我如何能够使用新的数据上下文而不是更改的数据上下文来运行IQueryable。

请在下面找到线程的示例代码:

var myQueryable = Global.DataContext.Customers.Where(a => a.Age <12);

ParallelLoopResult threads = Parallel.ForEach(groups, group =>
        {
            DataContext ctx = new DataContext(Const.ConnectionString);
            myFunction(myQueryable);
            ctx.Dispose();
        });

遗憾的是,在线程内部重写myQueryable的选项非常困难,因为生成它有很多逻辑。将其转换为列表然后传递它也不是一个选项,因为查询返回数千个条目并会对性能产生负面影响。

非常感谢任何帮助

1 个答案:

答案 0 :(得分:3)

我没有对此进行过测试,但我认为可行的方法是使用正确的Expression获取您的查询,但错误的Provider并将其与一个有权Provider,但错误Expression。为此,请使用CreateQuery()

var contextQueryable = ctx.Customers;

var fixedQueryable = contextQueryable.Provider.CreateQuery<Customer>(myQueryable.Expression);