一、问题的提出
目标:做出一张表,样式为:<应付款总额><已付款><当次应付款余额>
二、解决思路及实现步骤
1. 构造表1:订单Orders<int id, decimal total>(订单ID,订单总金额)
2. 构造表2:支付记录Payments<int id, decimal payment, datetime date>(订单ID,付款金额,付款发生日期)
3. 构造表3:对应每张订单每次支付记录的表PaymentList<int id, decimal total, decimal payment, datetime paydate>(订单ID,订单总金额,付款金额,付款发生日期)表3以Order的id为主键,通过外连接Orders与Payments表生成。
4. 构造表4:在表3基础上增加一个列:<decimal ramain>(当次余额)表4以表3为数据源,以每张订单的id为分类项,以当次付款发生日期为筛选条件,进行付款额的汇总,得到当次余额。
三、实现代码
using System; using System.Collections.Generic; using System.Linq; using System.Collections; namespace PaymentRecord { class Program { static void Main(string[] args) { // 构造演示所需的数据源,对应前述表1 Orders与表2 Payments 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") }); // 利用表1与表2,构造表3 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); // 在表3基础上进行分类汇总,增加列remain,构造出表4 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; } } }
四、运行结果:
{ id = 1, total = 80, payment = 20, remain = 60, paydate = 2011/6/2 0:00:00 } { id = 1, total = 80, payment = 40, remain = 20, paydate = 2011/6/4 0:00:00 } { id = 1, total = 80, payment = 10, remain = 10, paydate = 2011/6/12 0:00:00 } { id = 2, total = 100, payment = 30, remain = 70, paydate = 2011/6/8 0:00:00 } { id = 3, total = 20.5, payment = 0, remain = 20.5, paydate = 0001/1/1 0:00:00 }