0

如果可能,我想优化此查询并减少循环数。至少我必须首先选择所有客户端 ID 以进行迭代。任何帮助表示赞赏。

public DataTable convertCollectionExpectedToDatatable(List<Invoice> lst)
        {
            DataTable dtcollection = new DataTable();
            try
            {
                dtcollection.Columns.Add("ClientId", typeof(string));
                dtcollection.Columns.Add("customerName", typeof(string));
                dtcollection.Columns.Add("BalAmnt1", typeof(string));
                dtcollection.Columns.Add("BalAmnt2", typeof(string));
                dtcollection.Columns.Add("BalAmnt3", typeof(string));
                dtcollection.Columns.Add("totalAmt", typeof(string));

                DateTime promiseDate1 = DateTime.Today;
                DateTime promiseDate2 = promiseDate1.AddDays(1);
                DateTime promiseDate3 = promiseDate2.AddDays(1);

                var select = (from l in lst select l.ClientId).Distinct();
                List<long> lstInv = select.ToList<long>();

                DataRow dr;
                foreach (long inv in lstInv)
                {
                    decimal BalAmnt1 = lst.Where(Invoice => Invoice.ExpDt ==  
promiseDate1 && Invoice.ClientId == inv).Select(Invoice => Invoice.BalAmnt).Sum();
                    decimal BalAmnt2 = lst.Where(Invoice => Invoice.ExpDt == 
promiseDate2 && Invoice.ClientId == inv).Select(Invoice => Invoice.BalAmnt).Sum();
                    decimal BalAmnt3 = lst.Where(Invoice => Invoice.ExpDt == 
promiseDate3 && Invoice.ClientId == inv).Select(Invoice => Invoice.BalAmnt).Sum();

                    var clientName = (from l in lst where l.ClientId == inv select 
l.Client.Name).FirstOrDefault();

                    dr = dtcollection.NewRow();
                    dr["ClientId"] = inv.ToString();
                    dr["customerName"] = clientName.ToString();
                    dr["BalAmnt1"] = string.Format("{0:n2}", BalAmnt1);
                    dr["BalAmnt2"] = string.Format("{0:n2}", BalAmnt2);
                    dr["BalAmnt3"] = string.Format("{0:n2}", BalAmnt3);
                    dr["totalAmt"] = string.Format("{0:n2}", BalAmnt1 + BalAmnt2 + 
BalAmnt3);

                    dtcollection.Rows.Add(dr);
                }
            }
4

1 回答 1

0

您可以通过以下查询对发票进行分组ClientId并计算所有总和:

from invoice in lst
group invoice by invoice.ClientId into g
select new {
   BalAmnt1 = g.Where(i => i.ExpDt == promiseDate1).Sum(i => i.BalAmnt),
   BalAmnt2 = g.Where(i => i.ExpDt == promiseDate2).Sum(i => i.BalAmnt),
   BalAmnt3 = g.Where(i => i.ExpDt == promiseDate3).Sum(i => i.BalAmnt)
}

还要考虑更好的命名。什么名字lst会告诉那些阅读你的代码的人。如果这是发票列表,则将其命名为invoices。与 promiseDates 相同 -today并且tomorrow将更好地描述存储在变量中的日期:

DateTime today = DateTime.Today;
DateTime tomorrow = today.AddDays(1);
// don't know how to name dayAfterTomorrow
// suppose it has some business-specific name in your case

您还可以将重复的代码提取到单独的方法中:

public static decimal CalculateBalanceOn(
    this IEnumerable<Invoice> invoices, DateTime date)
{
    return invoices.Where(i => i.ExpDt == date).Sum(i => i.BalAmnt);
}

以上所有查询将如下所示:

from invoice in invoices
group invoice by invoice.ClientId into g
select new {
   BalanceToday = g.CalculateBalanceOn(today),
   BalanceTomorrow = g.CalculateBalanceOn(tomorrow),
   BalanceAfterTomorrow = g.CalculateBalanceOn(dayAfterTomorrow)
}
于 2013-07-16T06:42:37.993 回答