2

つまり、シナリオを一言で言えば、同じエンティティ (階層構造) 内の主キーへの外部キーを持つエンティティ (EF4) があります。

MyEntityId (主キー) ParentMyEntityId (主キーへの外部キー)

両方の EntityState が Unchanged である MyEntityList がある場合List<MyEntity>:

entity 1 - {MyEntityId = 10, ParentMyEntityId = null}
entity 2 - {MyEntityId = 11, ParentMyEntityId = 10}

そして、私はこれを行います:

//Initially has 2 items in 'in' clause - iterates once and then exits because the EntityState of the second item has changed to Modified
foreach(MyEntity m in MyEntityList.Where(e => e.EntityState == System.Data.EntityState.Unchanged))
{
     db.DeleteObject(m);
}

最初の MyEntity は削除されますが、2 番目は "Modified" に変更され、foreach は 2 回目は実行されません。外部キー制約が原因であると推測しています。

しかし、もしそうなら:

//Iterates twice, even though the EntityState of the second item has changed to Modified
foreach(MyEntity m in MyEntityList.Where(e => e.EntityState == System.Data.EntityState.Unchanged).ToList())
{
     db.DeleteObject(m);
}

両方のエンティティが削除されます (これは望ましい効果です)。

解決策はありますが、なぜこれが起こるのかに興味があります.foreachループの開始時に定義されたイテレータ「セット」が同じままであるか、実行しようとすると実行時エラーをスローしたという印象を常に受け​​ていました.それを変更します。

Whereを使用しないでください。これを行うより良い方法はありますか?

4

1 に答える 1

1

反復子セットは、実行するため、ループが実行される前に定義されますToList(これを行わないと、適切に定義されません)。

したがって、反復ソースは一定です。しかし、繰り返し処理するオブジェクトではありません。取得するオブジェクト参照は一定ですが、それらが指すオブジェクトではありません。

ToList のないバージョンは、次と同等です。

foreach(MyEntity m in MyEntityList) //always 2 items
{
     //loop body always called two times
     if (e.EntityState == System.Data.EntityState.Unchanged) //2 times
        db.DeleteObject(m); //1 time
}

ToList バージョンは次と同等です。

var copy = MyEntityList.Where(e => e.EntityState == System.Data.EntityState.Unchanged).ToList(); //always 2 items
foreach(MyEntity m in copy)
{
     //loop body always called two times
     db.DeleteObject(m); //2 times
}
于 2012-08-18T14:10:07.197 に答える