使用linq在foreach内部时,数据库被锁定而没有ToList()

时间:2016-05-11 10:49:58

标签: c# sql linq

我试过寻找答案却找不到答案。 '问题'很简单:

如果我使用linq收集项目如下:

var items = db.AnyTable.Where(x => x.Condition == condition).ToList();

使用linq但没有ToList()的另一个项目集合:

var items2 = db.AnyTable.Where(x => x.Condition == condition);

如果现在我尝试使用foreach迭代每个项目(我没有尝试while或其他类型的迭代方法):

foreach (var item in items) 
{
    int i = 2;// Doesn't matter, The important part is to put a breakpoint here.
}

如果我在断点处停止代码并尝试更新SQL Management Studio上的AnyTable,那么一切正常。如果!:

foreach (var item in items2) 
{
    int i = 2;// Doesn't matter, The important part is to put a breakpoint here.
}

如果现在我尝试更新(在断点处)SQL Management Studio上的AnyTable我将无法执行此操作(TimeOut)。

为什么ToList()会产生这样的差异?

根据我所学到的,特别的区别在于查询正在执行时(在items上,它在声明处执行,在items2上执行它在foreach语句上执行)。为什么这会阻止我更新AnyTable

2 个答案:

答案 0 :(得分:6)

当您访问数据时,linq查询仅转换为SQL查询。 当您调用ToList()时,您将创建一个SQL查询,该查询将所有数据返回到db中的代码。现在,项目var完全在内存中,并且不再对db进行任何工作。 在第二个示例中,您正在使用foreach,它在db中打开一个trnasaction, 当此事务仍处于打开状态时,您正在尝试更改数据 您将获得超时,因为该表由针对DB的打开LINQ查询保存。

答案 1 :(得分:0)

ToList()强制执行完整查询。

但是,如果您在没有ToList()的情况下枚举,那么它将根据需要进行查询。