操作集合以生成精简版本

时间:2013-02-13 17:57:17

标签: c# c#-4.0

我目前难以理解我似乎无法弄清楚的一小部分功能。

首先,我有一个Stock类,如下所示:

public class Stock
{
    public int Id;
    public int LocationId;
    public int Quantity;
}
从数据库返回

Stock个日志,这些日志是从另一个功能中生成的。该日志表示为List<Stock>集合 - 但我需要添加相同QuantityID组合的每个对象的LocationID属性,例如:

  

原始数据集:

     

ID:1位置:1个数量:20

     

ID:1位置:2数量:30

     

ID:1位置:1个数量:30

     

ID:2位置:2数量:20

     

ID:1位置:2数量:30

     

ID:1位置:1个数量:100

应该返回:

  

简明数据集:

     

ID:1位置:1个数量:150

     

ID:1位置:2数量:60

     

ID:2位置:2数量:20

重申:数据集是从数据库动态返回的,不能保证每个ID&amp; LocationID组合,我需要结果数据集在IDLocationID的复合键上是唯一的。

不确定最有效的解决方法,并且它阻碍了我对项目的进展,任何建议或方法都会非常感激。我有点认为这是一个知识差距,但我找不到合适的东西/符合我的要求(我猜这是一个非常奇怪的要求)。

非常感谢,

安迪

4 个答案:

答案 0 :(得分:2)

使用GroupBy执行此操作:

var grouped = (from s in stocks
                group s by new { s.Id, s.LocationId }
                    into grp
                    select new Stock()
                    {
                        Id = grp.Key.Id,
                        LocationId = grp.Key.LocationId,
                        Quantity = grp.Sum(x => x.Quantity)
                    }).ToList();

答案 1 :(得分:2)

最好在数据库上执行此操作,但您也可以使用GroupBy来实现完全相同的效果:

public class Stock
{
    public int Id;
    public int LocationId;
    public int Quantity;
}

static void Main(string[] args)
{
    var list = new List<Stock>()
        {
            new Stock(){ Id = 1, LocationId = 1, Quantity = 20},
            new Stock(){ Id = 1, LocationId = 2, Quantity = 30},
            new Stock(){ Id = 1, LocationId = 1, Quantity = 30},
            new Stock(){ Id = 2, LocationId = 2, Quantity = 20},
            new Stock(){ Id = 1, LocationId = 2, Quantity = 30},
            new Stock(){ Id = 1, LocationId = 1, Quantity = 100},

        };

    var grouped = list.GroupBy(c => new {Id = c.Id, LocationId = c.LocationId})
            .Select(g => new 
                 { 
                      Id = g.Key.Id, 
                      LocationId = g.Key.LocationId, 
                      Quantity = g.Sum(a => a.Quantity) 
                  });
    foreach(var group in grouped.OrderBy(c => c.Id))
    {
        Console.WriteLine("Id:{0} - LocationId:{1} - Quantity:{2}", group.Id, 
                 group.LocationId, group.Quantity);
    }
}

答案 2 :(得分:1)

我更喜欢使用这样的SQL查询:

select id, location, sum(quantity) quant from stocktable group by id, location

这有助于在db本身完成计算,从而在性能方面帮助您。由于数据库服务器无论如何都会读取并将所有数据提供给应用层,因此没有性能损失,您可以在简单性方面获益。

答案 3 :(得分:0)

您可以使用Enumerable.GroupBy执行分组,Enumerable.Aggregate(或者,在这种情况下是专门的Sum)来执行聚合。

有些事情:

IEnumerable<Tuple<int, int, int>> result =
    stocks.GroupBy(stock => new { id = stock.Id, locationId = stock.LocationId},
                   (key, s) => new { key.id, key.locationId, total = s.Sum(ss => ss.Quantity) });

foreach (var result in results)
{
    Console.WriteLine(result.id);
    Console.WriteLine(result.locationId);
    Console.WriteLine(result.total);
}