日期:2014-05-20 浏览次数:20839 次
订单编号 总价 order001 80
------解决方案--------------------
作为一个LINQ的新手,这样的题目很有挑战性。想了一个下午,终于想出来了,还请各位LINQ的高手进一步简化和改良,以进一步提高效率,消除冗余。
附上完整的测试代码:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Collections; namespace PaymentRecord { class Program { static void Main(string[] args) { ArrayList orders = new ArrayList(); orders.Add(new Order { _id = 1, _total = 80M }); orders.Add(new Order { _id = 2, _total = 100M }); orders.Add(new Order { _id = 3, _total = 20.5M }); ArrayList payments = new ArrayList(); payments.Add(new Payment { _id = 1, _payment = 20M, _date = DateTime.Parse("2011/06/02") }); payments.Add(new Payment { _id = 1, _payment = 40M, _date = DateTime.Parse("2011/06/04") }); payments.Add(new Payment { _id = 1, _payment = 10M, _date = DateTime.Parse("2011/06/12") }); payments.Add(new Payment { _id = 2, _payment = 30M, _date = DateTime.Parse("2011/06/08") }); var payrecords_1 = orders.OfType<Order>() .GroupJoin(payments.OfType<Payment>(), o => o._id, p => p._id, (o, ps) => ps.DefaultIfEmpty().Select(p => new { id = o._id, total = o._total, payment = (p != null) ? p._payment : 0, paydate = (p != null) ? p._date : (new DateTime(0)) })) .SelectMany(r => r); var payrecords_2 = payrecords_1.Select(s => new { id = s.id, total = s.total, payment = s.payment, remain = s.total - payrecords_1.Where(p => (p.id == s.id) && (p.paydate <= s.paydate)) .Sum(sum => sum.payment), paydate = s.paydate }); foreach (var item in payrecords_2) Console.WriteLine(item); } class Order { public int _id; public decimal _total; } class Payment { public int _id; public decimal _payment; public DateTime _date; } } }