简体   繁体   English

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

[英]C# Linq GroupBy, get list of a column in each group

I need to write a query to get all the shipping costs of sales, and compare it against an estimated shipping cost. 我需要编写查询以获取所有销售的运输成本,并将其与估计的运输成本进行比较。 Here is my query: 这是我的查询:

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();

It seems that doing anything with the group that isn't getting the group by keys or doing g.Count() makes the query run terribly slow, I can't get this query to finish without timing out. 似乎对没有通过键获取组的任何操作或执行g.Count()会使查询运行非常缓慢,如果没有超时,我无法使该查询完成。 Is there anything I can do to help performance here? 我可以做些什么来帮助提高表现吗?

Difficult to tell without all the database for test, but this line could be the problem : 很难在没有所有数据库进行测试的情况下进行判断,但是这行可能是问题所在:

(from gSales in g select gSales.ActualShipping)

Try this instead: 尝试以下方法:

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();

This prevent a second from . 这防止第二次from The first query might doing some weird joins, whereas with a simple Select it should not. 第一个查询可能会进行一些奇怪的连接,而使用简单的Select则不会。

I think problem can be caused by (from gSales in g select gSales.ActualShipping) . 我认为问题可能是由(from gSales in g select gSales.ActualShipping) Linq group by is translated into group by in SQL, so you don't have direct access to records which forms group. Linq group by在SQL中转换为group by ,因此您无权直接访问构成group的记录。 Each call of (from gSales in g select gSales.ActualShipping) will do separate select. 每次调用(from gSales in g select gSales.ActualShipping)都会进行单独的选择。

First possible solution: create index on ItemID, EstimatedShipping pair. 第一个可能的解决方案:在ItemID,EstimatedShipping对上创建索引。

Second possible solution: 第二种可能的解决方案:

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();

This will do grouping offline, after records are downloaded. 记录下载后,这将脱机分组。 It will for sure reduce number of queries, but you must check on your db to see if it's quicker. 它肯定会减少查询的数量,但是您必须检查数据库以查看它是否更快。

You can try performing the ActualShipping selection while you are building the result set: 您可以在构建结果集时尝试执行ActualShipping选择:

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

Not sure, but it could prevent additional enumeration. 不确定,但是它可能阻止其他枚举。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM