例如,我有一个具有以下DbSet的CustomDataContext类:
public DbSet<CustomClass> Classes { get; private set; }
以下2种情况有什么区别?
情况1:
using (var context = new CustomDataContext())
{
var something = ....;
var sql = $"SELECT * FROM dbo.mytable WHERE condition = {something}";
var items = context.Classes.SqlQuery(sql).ToList(); // <--- ToList()
foreach (var item in items)
{
...
}
}
情况2:
using (var context = new CustomDataContext())
{
var something = ....;
var sql = $"SELECT * FROM dbo.mytable WHERE condition = {something}";
var items = context.Classes.SqlQuery(sql); // <--- No ToList()
foreach (var item in items)
{
...
}
}
就性能而言,直接迭代可枚举/可查询对象是否有任何好处?我知道案例1发生了什么,但我不知道案例2发生了什么。有人可以向我解释吗?
答案 0 :(得分:1)
IEnumerable描述行为,而List是该行为的实现。使用IEnumerable时,可以使编译器有机会将工作推迟到以后,可能会一直进行优化。如果使用ToList(),则强制编译器立即对结果进行验证。
对于您列出的示例,没有明显的性能差异。
当我们利用延期执行的优势时,性能就来了。 LINQ不会生成SQL来查询数据库,直到您对它进行枚举。
考虑以下代码:
public IEnumerable<Vehicles> CaliEmissionStd()
{
return from a in EPA.RoadVehicles
where a.emissions.CaliEmissions == true
select a;
}
public IEnumerable<Vehicles> Cars(IEnumerable<Vehicles> vehicles)
{
return from a in vehicles
where a.VehType == "Car"
select a;
}
在这里,我们有一种方法可以选择所有符合cali排放标准的公路车辆,还有一个过滤器可以选择类型为car的子列表。
由于LINQ在枚举之前一直推迟构造查询,因此我们可以执行以下操作,以便最终得到一个SQL查询,该查询查询数据库并且仅返回相关的行。
var AutosWithCaliEmissionStd = Cars(CaliEmissionStd());
但是,如果我们从CaliEmissionStd()
返回了一个列表,那么它将运行得更慢,因为该数据库将返回所有具有cali排放标准的车辆(汽车,SUV,卡车,摩托车等)的数据,而不是只是汽车,导致我们浪费时间/时间在客户端进行过滤。