これらのクラスがあるとしましょう:
public class Car
{
public int CarId { get; set}
public virtual ICollection<Door> Doors { get; set}
}
public class Door
{
public int DoorId { get; set}
public decimal Weight { get; set}
public int CarId { get; set}
}
そして、私はこのようなことをしたい
foreach ( var car in db.Cars )
{
var x = car.Doors.Min(d => d.Weight);
}
EFTraceLog でわかるように、彼は Select * from Doors where CarId = @... のようなものを作成し、db サーバーではなくアプリケーション サーバーで "Min" を計算します
私は非常に大きな車とドアテーブルを持っているので、この操作は数分続きます. しかし、コードをこれに変更すると
foreach ( var car in db.Cars )
{
var x = db.Doors.Where(d => d.CarId == car.CarId).Min(d => d.Weight);
}
それから数秒です。
なぜこのような大きな違いがあり、どのように修正するのでしょうか? ここでの問題は、書くのがはるかに簡単だということです
var x = car.Doors.Min(d => d.Weight);
それから
var x = db.Doors.Where(d => d.CarId == car.CarId).Min(d => d.Weight);
アップデート
Entity Framework 5.0 を使用しています
更新 2
これらの亜種を試しましたが、遅いです
var x = car.Doors.Select(door => door.Weight).Min();
var x = car.Doors.OrderBy(x => x.Weight).Select(x => x.Weight).FirstOrDefault();
var x = car.Doors.OrderBy(x => x.Weight).Select(x => x.Weight).First();
var x = car.Doors.OrderBy(x => x.Weight).FirstOrDefault().Weight;
var x = car.Doors.OrderBy(x => x.Weight).First().Weight;
速いのはこれだけ
var x = db.Doors.Where(d => d.CarId == car.CarId).Min(d => d.Weight);
アップデート 3
最適なクエリはこの sql を生成します
declare @p__linq__0 Int32 = cast(N'204' as Int32);
SELECT
[GroupBy1].[A1] AS [C1]
FROM ( SELECT
MIN([Extent1].[Weight]) AS [A1]
FROM [dbo].[Doors] AS [Extent1]
WHERE [Extent1].[CarId] = @p__linq__0
) AS [GroupBy1]