Linq使用Aggregate()作为List

时间:2009-12-09 11:02:03

标签: c# linq

来自数据

OrderID     OrderAmt   OrderDate                                              
----------- ---------- --------------------
1           10.50      2003-10-11 08:00:00
2           11.50      2003-10-11 10:00:00
3           1.25       2003-10-11 12:00:00
4           100.57     2003-10-12 09:00:00
5           19.99      2003-10-12 11:00:00
6           47.14      2003-10-13 10:00:00
7           10.08      2003-10-13 12:00:00
8           7.50       2003-10-13 19:00:00
9           9.50       2003-10-13 21:00:00

我想显示以下运行总计

OrderId     OrderDate            OrderAmt   Running Total                        
----------- -------------------- ---------- ------------- 
1           2003-10-11 08:00:00  10.50      10.50
2           2003-10-11 10:00:00  11.50      22.00
3           2003-10-11 12:00:00  1.25       23.25
4           2003-10-12 09:00:00  100.57     123.82
5           2003-10-12 11:00:00  19.99      143.81
6           2003-10-13 10:00:00  47.14      190.95
7           2003-10-13 12:00:00  10.08      201.03
8           2003-10-13 19:00:00  7.50       208.53
9           2003-10-13 21:00:00  9.50       218.03

从以下列表中

List<OrderData> ord = new List<OrderData>();

ord.Add(new OrderData() { OrderNumber=1, OrderAmount=10.50, 
OrderDate=new DateTime(2003,10,11)});

ord.Add(new OrderData() { OrderNumber=2, OrderAmount=11.50,
OrderDate=new DateTime(2003,10,11)});

ord.Add(new OrderData() { OrderNumber=3, OrderAmount=1.25,
OrderDate=new DateTime(2003,10,11)});

ord.Add(new OrderData() { OrderNumber=4, OrderAmount=100.57,
OrderDate =new DateTime(2003,10,12)});

ord.Add(new OrderData() { OrderNumber=5, OrderAmount=19.99,
OrderDate=new DateTime(2003,10,12)});

ord.Add(new OrderData() { OrderNumber=6, OrderAmount=47.14,
OrderDate =new DateTime(2003,10,13)});

ord.Add(new OrderData() { OrderNumber=7, OrderAmount=10.08,
OrderDate=new DateTime(2003,10,13)});

ord.Add(new OrderData() { OrderNumber=8, OrderAmount=7.50,
OrderDate=new DateTime(2003,10,13)});

ord.Add(new OrderData() { OrderNumber=9, OrderAmount=9.50,
OrderDate=new DateTime(2003,10,13)});

如何重塑以下查询

var query = from o in ord
            select new
            {
             OrdNumber=o.OrderNumber,
             OrdDate=o.OrderDate,
             Amount=o.OrderAmount,
            RunntingTotal =ord.Aggregate(0,(o a,o b)=>
           {a.OrderAmount+b.OrderAmount;}) 
            };

2 个答案:

答案 0 :(得分:5)

您无法使用内置的Aggregate方法执行此操作。

Darin's answer会为您提供所需内容,但会产生副作用(即查询会在枚举时更新total变量)。

如果您想要一个没有副作用的“纯粹”查询,那么您需要创建某种Accumulate扩展方法并使用它而不是Aggregate

var query = ord.Accumulate(
    new { Order = (OrderData)null, Total = 0.0 },
    (a, x) => new { Order = x, Total = a.Total + x.OrderAmount });

foreach (var x in query)
{
    Console.WriteLine("{0}\t{1}\t{2}\t{3}",
        x.Order.OrderNumber, x.Order.OrderDate, x.Order.OrderAmount, x.Total);
}

// ...

public static class EnumerableExtensions
{
    public static IEnumerable<TAccumulate> Accumulate<TSource, TAccumulate>(
        this IEnumerable<TSource> source,
        TAccumulate seed,
        Func<TAccumulate, TSource, TAccumulate> func)
    {
        if (source == null)
            throw new ArgumentNullException("source");

        if (func == null)
            throw new ArgumentNullException("func");

        TAccumulate accumulator = seed;
        foreach (TSource item in source)
        {
            accumulator = func(accumulator, item);
            yield return accumulator;
        }
    }
}

答案 1 :(得分:2)

double total = 0;
var result = 
    (from o in ord
     select new
     {
         OrdNumber = o.OrderNumber,
         OrdDate = o.OrderDate,
         Amount = o.OrderAmount,
         RunntingTotal = total += o.OrderAmount
     }).ToArray();