假设我有这些课程:
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 中看到的那样,他从 CarId = @... 的 Doors 中选择 * 并在应用程序服务器上计算“Min”,而不是在 db 服务器上
我有很大的汽车和门桌,所以这个操作会持续几分钟。但是如果我将代码更改为此
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);
更新
我们正在使用实体框架 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]