更改 IQueryable 的 DataContext

Sam*_*ami 3 c# datacontext multithreading linq-to-sql task-parallel-library

我正在开发一个使用静态全局 DataContext 的项目(不推荐但目前极难更改)。我目前需要通过并行化一些独立的函数来提高某些部分的性能。由于 DataContext 不是线程安全的,因此我无法在新创建的线程内使用它。因此,我在每个线程内创建了一个新的 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();
        });
Run Code Online (Sandbox Code Playgroud)

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

非常感谢任何帮助

svi*_*ick 5

我还没有测试过这一点,但我认为可行的方法是让您的可查询性具有正确的Expression,但错误的Provider,并将其与具有正确的Provider,但错误的查询结合起来Expression。为此,请使用CreateQuery()

var contextQueryable = ctx.Customers.AsQueryable();

var fixedQueryable = contextQueryable.Provider.CreateQuery<Customer>(myQueryable.Expression);
Run Code Online (Sandbox Code Playgroud)