1

このコードには問題があります。intersect メソッドを実行すると、すべて正常に動作します。

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);   
}
4

4 に答える 4

1

これは、LINQクエリが遅延評価されているために発生します。結果は必要になるまで生成されません(呼び出したときはいつでもCount)。user.Rolesその間にCount変更すると、変更後に計算された計算が異なるのは当然のことです。

結果を「修正」する場合は、LINQに結果のローカルコピーを作成させる必要があります。たとえば、次のようになります。

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

このように、それ以降の操作matchedRolesは固定された「スナップショット」で機能し、自分自身を変更しない限り同じ結果を生成しますmatchedRoles

于 2011-12-01T15:56:24.547 に答える
1

Intersect遅延実行を使用します。つまり、結果を列挙するたびに、コードが実行されます。

したがって、2回目Countの呼び出しで列挙可能なものを2回列挙しmatchedRoles、の2回目の実行を引き起こしroles.Intersect(user.Roles)ます。ユーザーからロールを削除したため、アイテムが返されないようになりました。

これを回避するには、一度使用して結果を列挙しToList、そこから列挙された値を操作します。

var matchedRoles = roles.Intersect(user.Roles).ToList();
于 2011-12-01T15:56:39.960 に答える
0

Linqは遅延実行を使用します。つまり、基本的に2回交差します。一致したロールがuser.Rolesに残っている場合と、ロールを削除するための呼び出しの後に1回。

于 2011-12-01T15:56:52.360 に答える
0

LINQは、2回目にアクセスした瞬間に再度実行されます。参照のコピーを取得する場合は、ToListメソッドを使用して、そのアイテムを反復処理できます。

于 2011-12-01T15:57:29.357 に答える