0

我使用 MySQL(它不支持 MARS),我尝试并行运行多个SELECTs. 连接字符串是相同的,但是对于每个SELECT我创建另一个数据库上下文。

它看起来像这样:

using (var db = DataContextCreator.Instance.Create())
{
  return db.Customers
           .Where(it => it.customer_Id > 10)
           .Detach(db.Customers);
}

一句话Detach—​​—它是一个辅助方法,它需要一条记录或一堆记录。在第二种情况下,它列出了它们(使它们成为具体数据),并将记录从 db 上下文中分离出来(因此 GC 可以释放 db 上下文)返回分离的数据。

现在它给了我一个关于可怕的错误“已经有一个打开的 DataReader 与此连接关联,必须先关闭”。由于我没有明确使用 DataReader,我希望 100% 确定原因。

是因为我使用单个连接字符串来创建所有这些数据库上下文吗?或者换句话说——上述场景是否需要 MARS?

我问是因为我不想重新发明轮子,而且因为我所有的查询都相当小而且很快我正在考虑愚蠢的解决方法——在数据库上下文创建者中使用锁定。这样,每个块查询数据库都可以保证不与另一个并行执行。

4

2 回答 2

3

SqlConnectionMARS 仅在您对单个对象同时运行多个查询时才会考虑。

通常,每个DbContext对象都有自己的DbConnection对象,所以这可能不是这里的问题。

我认为这里的问题是,通过调用该Detach方法,您可能正在调用仍在执行的查询。

我建议使用AsNoTracking扩展方法来实现您的目标。

也就是说,我会将函数返回写为:

return db.Customers.Where(it => it.customer_Id > 10).AsNoTracking().ToList();
于 2013-01-19T21:12:45.520 回答
2

是因为我使用单个连接字符串来创建所有这些数据库上下文吗?

不,它不能是单个连接字符串的结果,我假设您的DataContextCreator.Instance.Create()返回上下文基于相同的连接。可以提供DataContextCreator代码吗?特别是财产Instance

于 2013-01-19T21:17:53.040 回答