2009-12-09 71 views
1

从数据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;}) 
      }; 

回答

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