2017-04-03 95 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

已更新我的答案 –