使用LINQ时,DataReader已经打开

时间:2010-04-22 15:50:03

标签: c# asp.net linq

我有一个包含静态字段的静态类,它引用了DataContext的包装器对象。

DataContext基本上是在我们创建dbml文件时由Visual Studio生成的。包含我们在DB中的每个存储过程的方法。

我们的类基本上有一堆静态方法可以触发这些存储过程中的每一种方法。然后根据LINQ查询返回一个数组。

示例:

public static TwoFieldBarData[] GetAgesReportData(string pct)
        {
                return DataContext
                .BreakdownOfUsersByAge(Constants.USER_MEDICAL_PROFILE_KEY, pct)
                .Select(x => new TwoFieldBarData(x.DisplayName, x.LeftValue, x.RightValue, x.TotalCount))
                .ToArray();
        }

我们偶尔会收到以下错误:

  

已经有一个开放的DataReader   与此命令相关联   必须关闭冷杉

这种情况间歇性地发生,我很好奇发生了什么。我的猜测是,当一个方法执行和下一个方法触发之间存在一些延迟时,它会锁定DataContext并抛出错误。

这可能是在DataContext中包含每个lock(){} LINQ调用以获得该类型的排他性并确保其他请求排队的情况吗?

3 个答案:

答案 0 :(得分:1)

DataContext并不意味着长寿,绝对不能用于多线程。

静态成员是长期存在的,可由多个线程访问。这场冲突可能是你问题的根源。

答案 1 :(得分:0)

锁定数据上下文可能会有问题,如果您不小心,它可能会破坏您的性能或让您陷入僵局。

这通常发生在您通过阅读器中的记录循环,然后尝试在其中运行另一个查询命令(例如,加载分层对象模型)

如果可能的话,尝试将MultipleActiveResultSets = True参数添加到您的连接字符串中,这通常可以比尝试单独调用更清晰地解决问题。

http://msdn.microsoft.com/en-us/library/cfa084cz(VS.80).aspx

另外,尽可能使用最小范围的数据上下文,如果愿意,可以使用单个“工作单元”。除非你需要维护一些状态,(比如加载一些对象然后一次性保存它们),你不应该重复使用数据上下文。

答案 2 :(得分:0)

正如布莱恩沃茨指出的那样。 DataContext应该是短暂的。确保在需要时和一小段时间内仅使用DataContext。

using(var db = new DataContext()) 
{
    // do your things here! 
}

希望它有所帮助!