使用linq在foreach内部时,数据库被锁定而没有ToList()
我试过寻找答案却找不到答案。 ‘问题’很简单:
如果我有一个使用linq的项目集合如下:
var items = db.AnyTable.Where(x => x.Condition == condition).ToList();
使用linq但没有ToList()
另一个项集合:
var items2 = db.AnyTable.Where(x => x.Condition == condition);
如果现在我尝试使用foreach迭代每个项目(我没有尝试使用或其他类型的迭代方法):
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
?
只有在访问数据时,linq查询才会转换为SQL查询。 当您调用ToList()时,您将创建一个SQL查询,该查询将所有数据返回到db中的代码。 现在,项目var完全在内存中,并且不再对数据库进行任何工作。 在第二个示例中,您正在使用foreach,它在db中打开一个trnasaction,并且在此事务仍处于打开状态时,您正在尝试更改将获得超时的数据,因为该表由打开的LINQ查询保持DB。
ToList()强制执行完整查询。
但是,如果您枚举没有ToList(),那么它将根据需要进行查询。