我使用MySQL(它不支持MARS),我尝试并行运行多个SELECT
。连接字符串是相同的,但是对于每个SELECT
,我创建另一个数据库上下文。
看起来像这样:
using (var db = DataContextCreator.Instance.Create())
{
return db.Customers
.Where(it => it.customer_Id > 10)
.Detach(db.Customers);
}
关于Detach
的一个词 - 它是一个带有记录或一堆记录的辅助方法。在第二种情况下,它会列出它们(使它们成为具体数据),并从db上下文中分离记录(因此GC可以释放数据库上下文)返回分离的数据。
现在它给了我一个关于可怕的错误“已经有一个与此Connection关联的开放DataReader必须先关闭”。由于我没有明确使用DataReader,我想100%确定原因。
是否因为我使用单个连接字符串来创建所有这些数据库上下文?换句话说 - 上述情况需要MARS吗?
我在问,因为我不想重新发明轮子,因为我所有的查询都很小而且很快我正在考虑愚蠢的解决方法 - 在db context creator中使用lock。这样,每个块查询数据库都可以保证不与另一个块并行执行。
答案 0 :(得分:2)
当您在单个SqlConnection
对象上同时运行多个查询时,MARS只是一个因素。
通常,每个DbContext
对象都有自己的DbConnection
对象,因此这可能不是问题。
我认为这里的问题是,通过调用Detach
方法,您可能在查询仍在执行时调用该查询。
我建议使用AsNoTracking
扩展方法来实现您的目标。
也就是说,我会将函数return写为:
return db.Customers.Where(it => it.customer_Id > 10).AsNoTracking().ToList();
答案 1 :(得分:2)
是因为我使用单个连接字符串来创建所有这些数据库上下文吗?
不,它不能是单个连接字符串的结果,我假设您的DataContextCreator.Instance.Create()
基于相同的连接返回上下文。你能提供DataContextCreator
代码吗?特别是财产Instance
。