2015-08-27 36 views
1

首先,我找到了解決我的問題的方法。問題是 - 有沒有更好的方法?Linq - 檢索數據一段時間(7天),即圖的訂單計數

我需要檢索一段時間(7天)的訂單清單列表,例如使用group by。在某些日子裏,沒有訂單,這意味着那些日子將被一羣人淘汰。

這是我需要什麼來實現(使用劍道UI條形圖):

A graph of orders for the last 7 days, some days with 0 orders

我在2個階段做到了這一點。第一個創建日期枚舉,第二個從數據庫檢索Orders的數量。

備註: db是一個實體框架數據上下文。 DbFunctions.TruncateTime()僅用於比較日期,忽略時間部分)。

var from = DateTime.Now.AddDays(-6); 
var to = DateTime.Now; 

var days = Enumerable.Range(0, 1 + to.Subtract(from).Days) 
      .Select(offset => from.AddDays(offset)) 
      .ToArray(); 

var data = days 
      .Select(i => new 
      { 
       Day = i.ToShortDateString(), 
       Orders = db.Orders.Count(d => DbFunctions.TruncateTime(o.OrderDate) == i.Date) 
      }); 

它可以做得更好嗎?在過去7天內檢索項目的數量/總和?

回答

0

我認爲這應該起作用。這個想法是首先篩選所有具有OrderDate範圍的訂單,然後填寫丟失的OrderDate,我們可以使用Concat附加一些默認日期(範圍內)。接下來我們使用GroupByOrderBy來準備投影。最後,我們正常進行投影,但請注意g.Count()應減少1,因爲我們附加了所有默認日期(使每個日期的訂單增加1)。

var data = db.Orders.Select(o => DbFunctions.TruncateTime(o.OrderDate)) 
        .Where(d => DbFunctions.DiffDays(DbFunctions.TruncateTime(DateTime.Now), d) < 7) 
        .Concat(Enumerable.Range(0,7).Select(i => DateTime.Now.Date.AddDays(-i) as DateTime?))  
        .GroupBy(d => d) 
        .OrderBy(g => g.Key) 
        .Select(g => new { 
           Day = g.Key.ToShortDateString(), 
           Orders = g.Count() - 1 
          }); 
+1

這不會因爲使用的GroupBy沒有訂單eleminate日期工作。見圖21/08/2015&25/08/2015。 –

+0

@Nikita是的我誤解了這個問題。之後,我嘗試尋找解決方法,並最終得到了更新的答案。 – Hopeless

+0

Enumerable有時間部分,所以目前我可能會得到兩條記錄,一條是2015年8月25日,另一條是2015年8月25日15:50:00。另外,爲什麼我們需要計數「 - 1」? –

0

此解決方案有一個主要問題,即每次查詢db.Orders時,如果Order有成千上萬的記錄,則這可能很貴。 是的,有一個更好的辦法:

var orderDictionary= (from ord in db.Orders 
        let dateOfOrder=DbFunctions.TruncateTime(ord.OrderDate) 
        where dateOfOrder>=fromDate && dateOfOrder<=toDate 
        group by dateOfOrder into ordGrp 
        select new {Key=ordGrp.Key,Count=ordGrp.Count()}).ToDictionary(o=>o.Key,o=>o.Count); 

var data=days.Select(i=>new 
        { Day=i.ToShortDateString(), 
         NoOfOrders=orderDictionary.ContainsKey(i.Date)?orderDictionary[i.Date]:null 
        });