我有以下方法可以进行一些分组
private List<CatalogVehicle> GroupResult(IEnumerable<VehicleAndQuote> vehiclesAndQuotes)
{
var vehicles = vehiclesAndQuotes
.GroupBy(vehicleAndQuote =>
new
{
vehicleAndQuote.Vehicle.VehicleMakeName,
vehicleAndQuote.Vehicle.VehicleModelTypeName,
vehicleAndQuote.Vehicle.VehicleEdition
})
.Select(a => new
{
vehicle = _mapper.Map<VehicleAndQuote, CatalogVehicle>(a.First()),
plans = GetLeasingpPlansGroupedByYearlyMileages(a.ToList()) //<== this one is taking ages
})
.Select(a =>
{
a.vehicle.LeasingPlans = a.plans;
return a.vehicle;
});
return vehicles.ToList();
}
以及其中要调用的方法;
private List<LeasingPlan> GetLeasingpPlansGroupedByYearlyMileages(IEnumerable<VehicleAndQuote> vehicleAndQuotes)
{
return vehicleAndQuotes.GroupBy(quote => quote.Quote.YearlyMileage)
.Select(group => _mapper.Map<List<VehicleAndQuote>, LeasingPlan>(group.ToList()))
.ToList();
}
最后一种方法花费很长时间。
IEnumerable<VehicleAndQuote> vehiclesAndQuotes
大约有30.000条记录。
我看不到任何性能提升者吗?
答案 0 :(得分:2)
我正在尝试将您的查询转换为对数据库更友好的版本。
var vehicles = vehiclesAndQuotes
.GroupBy(vehicleAndQuote =>
new {
vehicleAndQuote.Vehicle.VehicleMakeName,
vehicleAndQuote.Vehicle.VehicleModelTypeName,
vehicleAndQuote.Vehicle.VehicleEdition
})
.Select(a => new {
// DB friendly
vehicle = a.First(),
plans = a.GroupBy(quote => quote.Quote.YearlyMileage)
})
.AsEnumerable() // May o may not be needed / passing to LINQ to Objects
.Select(a => {
var vehicle = _mapper.Map<VehicleAndQuote, CatalogVehicle>(a.vehicle);
var plans = a.plans.Select(group => _mapper.Map<IEnumerable<VehicleAndQuote>, LeasingPlan>(group));
vehicle.LeasingPlans = plans;
return vehicle;
});
return vehicles.ToList(); // This should be avoided, specially if you are processing a large collection.
这样,您就可以在数据库端进行双重分组了。另外,直到最后我都没有实现整个系列。
希望这会有所帮助!
答案 1 :(得分:1)
在SQL Profiler
中检查生成的查询。您的查询正在对(N+1 problem)
和vehicle
中的每个记录plans
进行选择。如果您使用的是Entity Framework 2.0
,则应该知道它在本地运行GroupBy
,并且像SELECT *
一样从数据库中提取所有数据到内存中,然后将它们分组在内存中。在每个实体的多个查询中拆分查询。请勿在您的LINQ
LINQ函数中使用First()
之类的Select
函数,因为它会导致N+1 SQL Issue
。将EF版本升级到2.1或更高版本,以避免出现Local GroupBy
问题。