簡體   English   中英

如何改進這個LINQ查詢?

[英]How to improve this LINQ query?

我將不勝感激任何有關改進此linq查詢的建議。 我正在查詢發票清單,目的是找到每月發票總額最高的客戶。 然后我想顯示年,月,客戶和發票總額。

發票:

public class Invoice
{
    public string Customer { get; set; }
    public DateTime Date { get; set; }
    public double Amount { get; set; }
}

用於創建發票列表的數據上下文:

 public class DataContext
    {                
        private List<Invoice> _invoices;
        private List<string> _customers;

        public List<Invoice> Invoices
        {
            get
            {
                if (_invoices == null)
                {
                    _customers = new List<string>(){ "Jim", "John", "Jeff", "Joe", "Jack"};
                    _invoices = new List<Invoice>();
                    Random random = new Random();

                    for (int i = 0; i < 1000; i++)
                    {
                        _invoices.Add(new Invoice() {
                            Customer = _customers[random.Next(0, 5)], 
                            Date = new DateTime(random.Next(2010, 2015), random.Next(1, 13), random.Next(1, 20)),
                            Amount = random.Next(1,1000)
                        });                     
                    }
                }
                return _invoices;
            }
        }
    }

查詢:

 DataContext context = new DataContext();  

 var invoiceTotalsByMonth = from invoice in context.Invoices
                            group invoice by invoice.Date.Year into yearGroup
                            orderby yearGroup.Key
                            select new
                            {
                                 Year = yearGroup.Key,
                                 Months = from year in yearGroup
                                          group year by year.Date.Month into monthGroup
                                          orderby monthGroup.Key
                                          select new
                                          {
                                              Month = monthGroup.Key,
                                              CustomerTotals = from month in monthGroup
                                                               group month by month.Customer into customerGroup                                                                       
                                                               select new
                                                               {
                                                                   Customer = customerGroup.Key,
                                                                   Total = customerGroup.Sum(i=>i.Amount)
                                                               }
                                                  }
                                     };

            foreach (var year in invoiceTotalsByMonth)
            {
                Response.Write(year.Year + "<br/>");

                foreach (var month in year.Months)
                {
                    var maxCustomer = month.CustomerTotals.First(i => i.Total == month.CustomerTotals.Max(j => j.Total));

                    Response.Write(month.Month + ": " + maxCustomer.Customer + " - " + maxCustomer.Total.ToString("c") + "<br/>");
                }
            }    

謝謝你的建議。

那個怎么樣:

DataContext context = new DataContext();

var invoiceTotalsByMonthQuery = from i in context.Invoices
                                group i by new { i.Date.Year, i.Date.Month } into g
                                select new
                                {
                                    Year = g.Key.Year,
                                    Month = g.Key.Month,
                                    Customer = g.GroupBy(x => x.Customer)
                                                .Select(x => new { Name = x.Key, Total = x.Sum(y => y.Amount)})
                                                .OrderByDescending(x => x.Total)
                                                .First()
                                };

var invoiceTotalsByMonth = invoiceTotalsByMonthQuery.OrderBy(x => x.Year)
                                                    .ThenBy(x => x.Month);

foreach(var item in invoiceTotalsByMonth)
{
    Console.WriteLine("{0}/{1} - {2} ({3})", item.Month, item.Year, item.Customer.Name, item.Customer.Total);
}

一個忠告:它可能更好地使用OrderBy + First ,而不是First + Max與最高屬性值來尋找項目。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM