我希望优化此查询并尽可能减少循环次数。至少我必须首先选择所有客户端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);
}
}
答案 0 :(得分: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)
}