【问题标题】:Change DataContext of IQueryable更改 IQueryable 的 DataContext
【发布时间】:2015-06-08 10:04:10
【问题描述】:

我正在开发一个使用静态全局 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();
        });

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

非常感谢任何帮助

【问题讨论】:

  • 为什么不创建一个新的、相同的 IQueryable?将其创建封装在一个接受上下文作为参数的函数中,并从您想要的任何位置创建查询。此外,可查询对象 将在特定上下文中运行的查询——您不能更改它们的父对象。这就是为什么您应该拥有全局上下文的非常严重的原因之一
  • 我完全同意你的看法。但是以前的开发人员选择了这种方法,并且生成 IQueryable 的部分是紧密耦合的。所以我希望有一种方法可以将查询附加到不同的 DataContext 作为最简单和最快的解决方法。但似乎唯一的方法是更改​​该代码以接受 DataContext 作为参数。谢谢
  • Queryables 是可以执行的查询,它们不是查询定义。顺便说一句,您为什么要尝试并行执行多个 Queryable?这不会使任何东西运行得更快(相反)。您是否有一个您认为可以通过并行解决的性能问题?编写良好的 SQL 语句和适当的索引会更有效(效率高出数千倍)
  • 也许我对并行性部分提高了我的场景中的性能是错误的,但这只是一个临时解决方案。当前代码在 for 循环中运行 n 个读取查询。每个查询需要一秒钟的时间来运行。所以所有查询的总和很多。我在这里尝试通过单独运行独立查询来快速加快速度,直到我们重新编写函数。重写整个部分是可行的方法,但需要数周时间。我只是希望快速改进。
  • 您可能还想考虑将多个查询批处理在一起,以避免网络往返成本。如果每个查询需要 1 秒,则网络成本是一个重要问题。在 EF 中,您可以使用 EntityFramework.Extended 包和未来查询来执行此操作。它还支持批量更新/删除

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


【解决方案1】:

我还没有对此进行测试,但是我认为可行的方法是使用正确的 Expression 获取您的可查询性,但使用错误的 Provider 并将其与正确的 @ 相结合987654324@,但是错误的Expression。为此,请使用CreateQuery()

var contextQueryable = ctx.Customers;

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

【讨论】:

  • 这可行。当然,查询包含对数据上下文对象(例如表/实体集)的引用。但也许提供者并不依赖于此。
  • @usr 你是对的,在Expression 中切换DataContext(可能使用ExpressionVisitor)会更安全。
猜你喜欢
  • 2011-03-13
  • 1970-01-01
  • 2011-06-21
  • 1970-01-01
  • 2010-12-01
  • 1970-01-01
  • 2011-09-01
  • 1970-01-01
  • 2016-06-08
相关资源
最近更新 更多