C#Linq GroupBy,获取每个组中列的列表

时间:2013-10-29 13:46:35

标签: c# sql linq

我需要编写一个查询来获取销售的所有运费,并将其与估计的运费进行比较。这是我的疑问:

var sales = (from sale in db.Sales
             where sale.DateOfSale > startDate && sale.DateOfSale < endDate
             group sale by new {sale.ItemID, sale.EstimatedShipping} into g
             select new
             {
                 ItemID = g.Key.ItemID
                 Estimate = g.Key.EstimatedShipping
                 ActualShipCosts = (from gSales in g select gSales.ActualShipping)
             }).ToList();

似乎对没有通过键获取组或执行g.Count()的组执行任何操作会使查询运行速度非常慢,我无法在没有超时的情况下完成此查询。我能做些什么来帮助表演吗?

3 个答案:

答案 0 :(得分:0)

没有所有数据库进行测试很难说,但这一行可能是问题所在:

(from gSales in g select gSales.ActualShipping)

请改为尝试:

var sales = (from sale in db.Sales
             where sale.DateOfSale > startDate && sale.DateOfSale < endDate
             group sale by new {sale.ItemID, sale.EstimatedShipping} into g
             select new
             {
                 ItemID = g.Key.ItemID,
                 Estimate = g.Key.EstimatedShipping,
                 ActualShipCosts = g.Select(gSales => gSales.ActualShipping).ToList()
             }).ToList();

这会阻止第二个from。第一个查询可能会做一些奇怪的连接,而使用简单的选择它不应该。

答案 1 :(得分:0)

我认为问题可能由(from gSales in g select gSales.ActualShipping)引起。 Linq group by在SQL中被翻译为group by,因此您无法直接访问形成组的记录。 (from gSales in g select gSales.ActualShipping)的每次通话都会单独进行选择。

第一种可能的解决方案:在ItemID上创建索引,EstimatedShipping对。

第二种可能的解决方案:

var sales = (from sale in db.Sales
         where sale.DateOfSale > startDate && sale.DateOfSale < endDate
         select new
         {
             ItemID = sale.ItemID
             Estimate = sale.EstimatedShipping
             ActualShipCosts = sale.ActualShipping
         }).ToList();

var groupedSales = (from sale in sales
         group sale by new {sale.ItemID, sale.EstimatedShipping} into g
         select new
         {
             ItemID = g.Key.ItemID,
             Estimate = g.Key.EstimatedShipping,
             ActualShipCosts = g.Select(gSales => gSales.ActualShipping).ToList()
         }).ToList();

这将在下载记录后离线分组。它肯定会减少查询次数,但您必须检查数据库以查看它是否更快。

答案 2 :(得分:0)

您可以在构建结果集时尝试执行 ActualShipping 选项:

var sales = db.Sales
    .Where(sale => sale.DateOfSale > startDate && sale.DateOfSale < endDate)
    .GroupBy(
        sale => new {sale.ItemID, sale.EstimatedShipping},
        sale => sale.ActualShipping)
    .ToList();

不确定,但可能会阻止额外的枚举。