2017-04-03 97 views
2

說我有一些類是這樣的:LINQ - 集團通過計算領域

public class MyClass 
{ 
    public DateTime Date { get; set; } 
    public string Code { get; set; } 
} 

而像一些值:

| Date   | Code | 
|------------ |------ | 
| 03/04/2017 | 1234 | 
| 31/03/2017 | 1234 | 
| 29/03/2017 | 1234 | 
| 29/03/2017 | 4321 | 
| 25/03/2017 | 4321 | 
| ...   | ... | 

我想通過Code領域,也羣組這些由日期但是我希望日期按範圍分組。這個計算會發現在本週(即一週的星期一)開始,並在本週結束之日(即本週五),然後給我一些成果,如:

| 03/04/2017 | 1234 | < week beginning 03/04 and code=1234 

| 31/03/2017 | 1234 | < week beginning 27/03 and code=1234 
| 29/03/2017 | 1234 | 

| 29/03/2017 | 4321 | < week beginning 27/03 and code=4321 

| 25/03/2017 | 4321 | < week beginning 20/03 and code=4321 

我已經試過做一個範圍,但我覺得我在做什麼是很沒用(StartOfWeekhere擴展方法):

data.Where(d => d.Date >= d.Date.StartOfWeek(DayOfWeek.Monday) && d.Date <= d.Date.StartOfWeek(DayOfWeek.Monday).AddDays(6)); 

注:我使用實體框架爲我的實際項目,但是當我這樣做我正在從MyClass表中獲取所有數據,並且我想要完成以上所有步驟以適當地過濾和分組數據。

+1

這是在LINQ到對象,LINQ to SQL的,EF,別的東西嗎? –

+0

@JonSkeet我對我的實際項目使用EF,這只是我面臨的問題的一個粗略示例。我的基礎數據全部在SQL中,並通過EF(UnitOfWork)訪問。 – Toby

+3

沒錯,但是這個細節真的很重要 - 例如,在LINQ to Objects中工作的解決方案在EF中可能無法正常工作。 –

回答

0

下面的代碼使用星期日作爲一週的第一天。要獲得星期,您需要將年中的日劃分爲7.如果一年中的第一天是星期一,則需要將年份中的星號加1以便星期幾爲星期日= 0,星期一= 1 ,....自1月1日是第1天(而不是0),因此除法方法正常工作。

  DataTable dt = new DataTable(); 
      dt.Columns.Add("Date",typeof(DateTime)); 
      dt.Columns.Add("Code",typeof(int)); 

      dt.Rows.Add(new object[] { DateTime.Parse("04/03/2017"), 1234}); 
      dt.Rows.Add(new object[] { DateTime.Parse("03/31/2017"), 1234}); 
      dt.Rows.Add(new object[] { DateTime.Parse("03/29/2017"), 1234}); 
      dt.Rows.Add(new object[] { DateTime.Parse("03/29/2017"), 4321}); 
      dt.Rows.Add(new object[] { DateTime.Parse("03/25/2017"), 4321}); 

      var groups = dt.AsEnumerable().GroupBy(x => (int)(x.Field<DateTime>("Date").DayOfYear + (int)new DateTime(x.Field<DateTime>("Date").Year, 1, 1).DayOfWeek)/7).ToList(); 
0

我試圖通過code使用週數,所以第一組,然後weekOfYear + Year

List<MyClass> date = new List<MyClass> 
{ 
    new MyClass { Date = new DateTime(2017,03,04), Code = "1234"}, 
    new MyClass { Date = new DateTime(2017,03,05), Code = "1234"}, 
    new MyClass { Date = new DateTime(2017,03,06), Code = "1234"}, 
    new MyClass { Date = new DateTime(2017,04,04), Code = "1234"}, 
    new MyClass { Date = new DateTime(2017,04,05), Code = "1234"}, 
    new MyClass { Date = new DateTime(2017,04,06), Code = "1234"}, 
    new MyClass { Date = new DateTime(2017,03,06), Code = "12345"}, 
    new MyClass { Date = new DateTime(2017,04,04), Code = "12345"}, 
    new MyClass { Date = new DateTime(2017,04,05), Code = "12345"}, 
    new MyClass { Date = new DateTime(2017,04,06), Code = "12345"} 
      }; 

var groupbydata = date.GroupBy(x => x.Code).ToDictionary(x => x.Key, x => x.GroupBy(y => CultureInfo.InvariantCulture.Calendar.GetWeekOfYear(y.Date, CalendarWeekRule.FirstFullWeek, DayOfWeek.Monday).ToString() + y.Date.Year.ToString())); 

更新

我已經改變了

x => x.GroupBy(y => CultureInfo.InvariantCulture.Calendar.GetWeekOfYear(y.Date, CalendarWeekRule.FirstFullWeek, DayOfWeek.Monday) + y.Date.Year)); 

x => x.GroupBy(y => CultureInfo.InvariantCulture.Calendar.GetWeekOfYear(y.Date, CalendarWeekRule.FirstFullWeek, DayOfWeek.Monday).ToString() + y.Date.Year.ToString())); 

你會得到 Dictionary<string, IEnumerable<IGrouping<string, MyClass>>>Key的字典是Code和詞典的ValueWeek number + Year

亦自數據嘗試打印出來

private static void Print(Dictionary<string, IEnumerable<IGrouping<string, MyClass>>> groupbydata) 
    { 
     foreach (var d1 in groupbydata) 
     { 
      Debug.WriteLine("Code : " + d1.Key); 

      foreach (var d2 in d1.Value) 
      { 
       Debug.WriteLine("Week number + Year: " + d2.Key); 
       foreach (var d3 in d2) 
       { 
        Debug.WriteLine("Date : " + d3.Date); 
       } 
      } 
     } 
    } 

,其結果是

代碼:1234

週數+年:92017

日期:3/4/2 017 12:00:00 AM

日期:2017年3月5日12:00:00 AM

週數+年份:102017

日期:2017年3月6日12:00:00 AM

週數+年份:142017

日期:2017年4月4日12:00:00 AM

日期:2017年4月5日12:00:00 AM

日期:2017年4月6日12:00:00 AM

代碼:12345

週數+年份:102017

日期:2017年3月6日12:00:00 AM

週數+年份:142017

日期:2017年4月4日12:00:00 AM

日期:2017年4月5日12:00:00 AM

日期:2017年4月6日12:00:00 AM

+0

這是什麼「鑰匙」?如何迭代在查詢中捕獲的組,因爲有2個組?你可以添加一個例子來說明我如何做到這一點? (對不起,我不是很熟悉C#/ LINQ) – Toby

+0

已更新我的答案 –