2012-02-21 11 views
0

IQueryable<Car> carsと言います。延期実行値は変更されていません

foreach (Car c in cars) 
{ 
    c.Doors = 2; 
} 

はなぜc.Doorsが代わりに変更された値で、foreachの後に元の値が含まれていない:私はそのように反復

は、あなたがたIQueryableが正しい文でないエンティティクエリにLINQの結果であることが示され、事前に

+0

列挙する前にリストに変換すれば、正しい結果が得られることが分かります。 – Dante

+0

IQueryable の実装では、各繰り返しで新しいセットが生成されるか、Car.Doorsのセッターが「破損」します。 IQuerable が作成された場所を表示してください。 – Polity

+0

IQueryable は、Linq to Entitiesクエリの結果です。 Linqクエリでは、値をプロパティDoorsに割り当てることができるので、セッタは問題ありません。 – Dante

答えて

1

、ありがとうございました。 MyDatabaseContext.Cars.Where(x => x.Name == "Test")はIQueryableを返します。反復処理では、データベースのクエリが完了します。 (反復はあなたがその上でforeachを実行するときです)。それでは、結果セットはまだ含まれていません。単にクエリだけです。

車に2回ループすると、2つの同一のクエリがデータベースに生成され、2つの同一の結果セットが返されます。データを保存したい場合。 ToArrayまたはToListを呼び出すか、または操作後に変更を保存してから、再度反復処理を行う必要があります。

+0

おそらく私の部分ではフレーズが悪いかもしれませんが、IQueryable自体がクエリを実行しないことがわかります。だから、それを反復すると、クエリは一度実行されます。反復処理後にToList()を実行すると、クエリが再度実行されます。右? – Dante

+0

ToListは内部的にもソースを反復します。 – Polity

1

IQueryableは、結果セットをデータベースから取得しますが、これはわかっていると思います。この状況やその他の状況で私が見たことは、この結果がキャッシュされないことです。したがって、IQueryableの反復処理が実際に再度クエリを実行することがよくあるため、変更が保存されないことがよくあります。そのコードの影響を受けなかった新しい結果セット。

ToList()を最初に呼び出してその結果を反復する理由は、ToList()が結果セット全体を取得してマテリアライズし、データベースコンテンツにリンクされなくなったためですデータベースが返されました。

変更が確実に行われるようにするには、データのローカルコピーを操作するしかありません。すなわち、IQueryableの土地から持ち上げてください。これは、結果セットのIEnumerable(つまり結果はToEnumerable())を保存するのと同じくらい単純なものになります。列挙するたびに同じ結果セットが返されますが、ToList()とは異なり、すぐに評価されません。

関連する問題