我正在开发一个使用静态全局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的选项非常困难,因为生成它有很多逻辑。将其转换为列表然后传递它也不是一个选项,因为查询返回数千个条目并会对性能产生负面影响。
非常感谢任何帮助
答案 0 :(得分:3)
我没有对此进行过测试,但我认为可行的方法是使用正确的Expression
获取您的查询,但错误的Provider
并将其与一个有权Provider
,但错误Expression
。为此,请使用CreateQuery()
:
var contextQueryable = ctx.Customers;
var fixedQueryable = contextQueryable.Provider.CreateQuery<Customer>(myQueryable.Expression);