列表.数据库结果在每次操作后都在变化

本文关键字:变化 操作 数据库 结果 列表 | 更新日期: 2023-09-27 18:16:16

我有一个问题,这段代码,当我做我的相交方法一切工作正常。

当我在foreach之前对交点进行计数时,结果是1。

在foreach之后,如果在foreach之后再次计数,结果是0,为什么会发生这种情况?它应该总是1…

var matchedRoles = roles.Intersect(user.Roles);
int before = matchedRoles.Count();
foreach (var matchedRole in matchedRoles)
{
    user.Roles.Remove(matchedRole);
}
int after = matchedRoles.Count();
if (matchedRoles.Any())
{
    accountRepository.Update(user);   
}

列表.数据库结果在每次操作后都在变化

这是因为LINQ查询是惰性求值的:直到需要时才产生结果(即调用Count时)。因此,如果同时修改user.Roles,则修改后的Count计算结果将不同。

如果你想"修复"结果,那么你必须强制LINQ做一个结果的本地副本,例如:

// Here, ToArray() forces LINQ to immediately produce the results
var matchedRoles = roles.Intersect(user.Roles).ToArray();

这样,只要不修改matchedRoles本身,对matchedRoles的任何进一步操作都将在固定的"快照"上工作并产生相同的结果。

Intersect使用延迟执行。这意味着,每次枚举结果时,都会执行代码。

因此,对Count的第二次调用再次枚举matchedRoles可枚举对象,从而导致roles.Intersect(user.Roles)的第二次执行。因为您从用户中删除了角色,所以它现在不返回任何项。

为了避免这种情况,使用ToList枚举一次结果,并从那里使用枚举值:

var matchedRoles = roles.Intersect(user.Roles).ToList();

Linq使用延迟执行:它本质上做两次相交。匹配的角色仍然在user中。

你的LINQ会在你第二次访问它的时候再次被执行。如果您想获得引用的副本,您可以使用ToList方法并遍历其项