为了账号安全,请及时绑定邮箱和手机立即绑定

linq 分组结果需要很长时间

linq 分组结果需要很长时间

C#
米琪卡哇伊 2021-11-07 19:06:00
我有以下方法可以进行一些分组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的记录。有没有我没有看到的性能提升器?
查看完整描述

2 回答

?
慕村225694

TA贡献1880条经验 获得超4个赞

我正在尝试将您的查询转换为对数据库更友好的版本。


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.

这样您就可以在数据库端进行双重分组。另外,我直到最后才将整个系列具体化。


查看完整回答
反对 回复 2021-11-07
?
四季花海

TA贡献1811条经验 获得超5个赞

检查中生成的查询SQL Profiler。您的查询正在(N+1 problem)vehicle和 中的每条记录进行选择plans。如果您正在使用Entity Framework 2.0,您应该知道它在GroupBy本地运行并将所有数据从数据库中提取到内存中SELECT *,然后将它们分组到内存中。将您的查询分解为每个实体的多个查询。不要LINQFirst()SelectLINQ函数中那样使用函数,因为它会导致N+1 SQL Issue. 将您的 EF 版本升级到 2.1 或更高版本以避免Local GroupBy出现问题。


查看完整回答
反对 回复 2021-11-07
  • 2 回答
  • 0 关注
  • 217 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信