C# 更改IQueryable的DataContext

C# 更改IQueryable的DataContext,c#,multithreading,linq-to-sql,task-parallel-library,datacontext,C#,Multithreading,Linq To Sql,Task Parallel Library,Datacontext,我正在从事一个使用静态全局DataContext的项目(不推荐使用,但目前很难更改)。我目前需要通过并行化一些独立的函数来提高某些部分的性能。因为DataContext不是线程安全的,所以我不能在新创建的线程中使用它。因此,我在每个线程内创建了一个新的DataContext,并在线程末尾处理它 新的datacontext一切正常,但我有一个问题,即函数的输入之一是附加到全局datacontext的IQueryable。运行该方法将导致异常“已存在与此命令关联的打开的DataReader,必须先关

我正在从事一个使用静态全局DataContext的项目(不推荐使用,但目前很难更改)。我目前需要通过并行化一些独立的函数来提高某些部分的性能。因为DataContext不是线程安全的,所以我不能在新创建的线程中使用它。因此,我在每个线程内创建了一个新的DataContext,并在线程末尾处理它

新的datacontext一切正常,但我有一个问题,即函数的输入之一是附加到全局datacontext的IQueryable。运行该方法将导致异常“已存在与此命令关联的打开的DataReader,必须先关闭该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();
        });
var myQueryable=Global.DataContext.Customers.Where(a=>a.Age
{
DataContext ctx=新的DataContext(Const.ConnectionString);
myFunction(myQueryable);
ctx.Dispose();
});
不幸的是,在线程内部重新编写myQueryable的选项相当困难,因为要生成它需要大量的逻辑。将其转换为list然后传递它也不是一个选项,因为查询返回数千个条目,这会对性能产生负面影响


非常感谢您提供的任何帮助

我没有测试过这一点,但我认为可行的方法是使用正确的
表达式
,但使用错误的
提供程序
,并将其与具有正确的
提供程序
,但使用错误的
表达式的提供程序相结合。为此,请使用:

var contextQueryable=ctx.Customers;
var fixedQueryable=contextQueryable.Provider.CreateQuery(myQueryable.Expression);

为什么不创建一个新的、相同的IQueryable?将其创建封装在一个函数中,该函数接受上下文作为参数,并从任意位置创建查询。此外,查询文件是将在特定上下文上运行的查询,您不能更改它们的父项。这是你不应该拥有全球环境的一个非常重要的原因。我完全同意你的观点。但是以前的开发人员选择了这种方法,并且生成IQueryable的部分是紧密耦合的。因此,我希望找到一种将查询附加到不同的DataContext的方法,作为最简单、最快速的解决方法。但似乎唯一的方法是更改代码以接受DataContext作为参数。Thankskyables是准备好执行的查询,而不是查询定义。顺便说一句,为什么要并行执行多个Queryable?这不会让任何东西跑得更快(相反)。您是否有一个您认为可以通过并行性解决的性能问题?一条写得好的SQL语句和适当的索引要有效得多(效率要高出数千倍)。在我的场景中,关于提高性能的并行部分,也许我错了,但它只是一个临时解决方案。当前代码在for循环中运行n个读取查询。每个查询运行一秒钟。因此,所有查询的总和非常大。我在这里试图通过分别运行独立的查询来加快速度,直到我们重新编写函数为止。重写整个部分是一条路要走,但需要几个星期。我只是希望能有一个快速的改进。您可能还想研究将多个查询批处理在一起,以避免网络往返成本。如果每个查询需要1秒的时间,则网络成本是一个重要问题。在EF中,您可以对包和将来的查询执行此操作。它还提供对批更新/删除的支持。这可能会起作用。当然,查询包含对datacontext对象(如表/EntitySet)的引用。但可能提供者并不依赖于此。@usr您是对的,在
表达式
中也切换
数据上下文
(可能使用
表达式访问者
)会更安全。
var contextQueryable = ctx.Customers;

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