如何优化此linq查询以减少循环?

如何优化此linq查询以减少循环?,linq,linq-to-entities,refactoring,Linq,Linq To Entities,Refactoring,如果可能的话,我想优化这个查询并减少循环的数量。至少是为了迭代,我必须首先选择所有客户机id的那个。 谢谢你的帮助 public DataTable convertCollectionExpectedToDatatable(List<Invoice> lst) { DataTable dtcollection = new DataTable(); try { dtc

如果可能的话,我想优化这个查询并减少循环的数量。至少是为了迭代,我必须首先选择所有客户机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);
                }
            }
公共数据表ConvertionExpectedToDataTable(列表lst)
{
DataTable dtcollection=新DataTable();
尝试
{
Add(“ClientId”,typeof(string));
Add(“customerName”,typeof(string));
添加(“BalAmnt1”,typeof(string));
添加(“BalAmnt2”,typeof(string));
添加(“BalAmnt3”,typeof(string));
Add(“totalAmt”,typeof(string));
DateTime promiseDate1=日期时间。今天;
DateTime promiseDate2=promiseDate1.添加天数(1);
DateTime PromiseDate 3=PromiseDate 2.添加天数(1);
var select=(从lst select l.ClientId.Distinct()中的l开始);
List lstInv=select.ToList();
数据行dr;
foreach(第一库存中的长库存)
{
十进制余额t1=lst.其中(发票=>Invoice.ExpDt==
promiseDate1&&Invoice.ClientId==inv)。选择(Invoice=>Invoice.BalAmnt.Sum();
十进制余额2=lst.其中(发票=>Invoice.ExpDt==
promiseDate2&&Invoice.ClientId==inv)。选择(Invoice=>Invoice.BalAmnt.Sum();
十进制余额3=lst.其中(发票=>Invoice.ExpDt==
promiseDate3&&Invoice.ClientId==inv)。选择(Invoice=>Invoice.BalAmnt.Sum();
var clientName=(从lst中的l开始,其中l.ClientId==inv select
l、 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+
平衡3);
dtcollection.Rows.Add(dr);
}
}

您可以按
客户ID对发票进行分组,并使用此查询计算所有金额:

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<代码>将告诉人们谁将读取您的代码。如果这是一个发票清单,然后命名它“代码>发票< /代码>。同样,与允诺-<代码>今天< /代码>和<代码>明天<代码>将更好地描述存储在变量中的日期:

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

至少这一行
List lstInv=select.ToList();
完全没有必要。您可以在不创建列表的情况下对不同的ID进行迭代。谢谢您的即时回复。我想知道在将此查询的输出存储在列表中时,如何才能使用此查询的输出填充数据表。该解决方案在优化方面起作用。只是想让您知道这是一个进一步的问题…@JayantShelke不将其存储在列表中。此查询生成强类型的匿名对象。只需对它们进行迭代,例如,
foreach(查询中的var项){dr[“BalAmnt1”]=String.Format(“{0:n2}”,item.BalAmnt1);…}
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)
}