私が持っていると言いますIQueryable<Car> cars
。
私はそれを次のように繰り返します:
foreach (Car c in cars)
{
c.Doors = 2;
}
c.Doors
変更された値ではなく、foreachの後に元の値が含まれるのはなぜですか?
前もって感謝します
私が持っていると言いますIQueryable<Car> cars
。
私はそれを次のように繰り返します:
foreach (Car c in cars)
{
c.Doors = 2;
}
c.Doors
変更された値ではなく、foreachの後に元の値が含まれるのはなぜですか?
前もって感謝します
IQueryable
ご存知のとおり、リトリーブを繰り返すと、データベースから結果セットが取得されます。この状況や他の状況で私が観察したのは、この結果はキャッシュされないため、IQueryable
もう一度繰り返すと実際にクエリが再度実行されることがよくあります。したがって、新しいものを取得しているため、変更は保持されません。そのコードの影響を受けなかった結果セット。
ToList()
最初に呼び出してその結果を反復処理するときに機能する理由ToList()
は、結果セット全体を取得してマテリアライズするためです。結果セットはデータベースコンテンツにリンクされなくなり、実際にはデータベースが返したものの単なるコピーになります。
変更が確実に反映されるようにする唯一の方法は、データのローカルコピーを操作することです。つまり、データをIQueryable
土地から持ち上げます。IEnumerable
これは、結果セット(つまりの結果)を保存するのと同じくらい簡単です。これによりToEnumerable()
、列挙するたびに同じ結果セットが返されますが、ToList()
すぐには評価されません。
IQueryableは、正しいステートメントではないエンティティクエリへのlinqの結果であると指定しました。MyDatabaseContext.Cars.Where(x => x.Name == "Test")は、反復時にデータベースでクエリを実行するIQueryableを返します。(反復とは、foreachを実行することです)。したがって、結果セットはまだ含まれていません。クエリのみが含まれています。
車を2回ループすると、データベースに対して2つの同一のクエリが生成され、2つの同一の結果セットが返されます。データを保存したい場合。ToArrayまたはToListを呼び出す必要があります。または、操作後に、再度反復する前に変更の保存を実行します。