【问题标题】:Group by Week of year (Week number) in Linq to SQL在 Linq to SQL 中按一年中的第几周(周数)分组
【发布时间】:2010-08-06 21:22:51
【问题描述】:

在常规 SQL 中,我可以执行类似的操作

SELECT * From T GROUP BY DATEPART(wk, T.Date)

我如何在 Linq to SQL 中做到这一点?

以下不起作用

From F In DB.T Group R By DatePart(DateInterval.WeekOfYear, F.Date)

也不行:

From F In DB.T Group R By (F.Date.DayOfYear / 7)

【问题讨论】:

  • 当你说它不起作用时,你是什么意思?不编译,不返回预期结果?
  • 不编译.. "范围变量名只能从不带参数的简单名称或限定名称中推断出来。"
  • 好的,答案是“来自 DB.T Group R 中的 F By WeekOfYear = (F.Date.DayOfYear / 7)”

标签: c# sql-server vb.net linq-to-sql week-number


【解决方案1】:

LINQ to SQL 不支持 Calendar.WeekOfYear 方法,但您可能会创建 TSQL function that wraps the call to DatePart。 DayOfYear / 7 技巧应该适用于大多数情况并且更容易使用。这是我最终得到的代码:

var x = from F in DB.T
        group F by new {Year = F.Date.Year, Week = Math.Floor((decimal)F.Date.DayOfYear / 7)} into FGroup
        orderby FGroup.Key.Year, FGroup.Key.Week
        select new {
            Year = FGroup.Key.Year,
            Week = FGroup.Key.Week,
            Count = FGroup.Count()
        };

结果如下:

Year    Week    Count
2004    46      3
2004    47      3
2004    48      3
2004    49      3
2004    50      2
2005    0       1
2005    1       8
2005    2       3
2005    3       1
2005    12      2
2005    13      2

【讨论】:

  • 请记住,这不会直接对应于日历周,因为它假定一年总是从星期日开始。要完全匹配,您需要使用 Calendar.WeekOfYear 或将 DatePart 调用包装到 SQL 函数中
【解决方案2】:

您可以使用System.Data.Entity.SqlServer 命名空间中的SqlFunctions.DatePart 方法。

// Return the week number
From F In DB.T Group R By SqlFunctions.DatePart("week", F.Date)

【讨论】:

    【解决方案3】:
    【解决方案4】:

    这可以正常工作。

    from F in DB.T group F by F.Date.DayOfYear / 7;
    

    您指定的组不正确。此代码的结果是对象的集合。每个对象都有一个 Key 属性,它是您分组的依据(在本例中是 F.Date.DayOfYear / 7 的结果。每个对象都是 T 中满足分组条件的对象的集合。

    【讨论】:

    • 我所要做的就是“From F In DB.T Group R By WeekOfYear = (F.Date.DayOfYear / 7)”;)
    【解决方案5】:

    如果您担心您在以下代码中所处的文化,则会考虑到这一点:

    var ci = CultureInfo.CurrentCulture;
    var cal = ci.Calendar;
    var rule = ci.DateTimeFormat.CalendarWeekRule;
    var firstDayOfWeek = ci.DateTimeFormat.FirstDayOfWeek;
    
    var groups = from F in DB.T
                 group F by cal.GetWeekOfYear(F, rule, firstDayOfWeek) into R
                 select R;
    

    【讨论】:

    • 这不起作用--“方法 'Int32 GetWeekOfYear(System.DateTime, System.Globalization.CalendarWeekRule, System.DayOfWeek)' 不支持对 SQL 的转换。”
    • Linq2Sql 或 Linq to Entities 似乎不支持 Calendar.GetWeekOfYear;您将首先提取整个数据集,然后使用 cal.GetWeekOfYear(x, rule, firstDayOfWeek)。
    • 是的.. 但是将 DayOfYear 除以 7 足以满足我的需要。谢谢!
    【解决方案6】:

    首先你应该得到一周中第一天的日期。

    获取一周中第一天的日期。 您可以使用此代码:

    public static class DateTimeExtensions
    {
        public static DateTime StartOfWeek(this DateTime dt, DayOfWeek startOfWeek)
        {
            int diff = dt.DayOfWeek - startOfWeek;
            if (diff < 0)
            {
                diff += 7;
            }
            return dt.AddDays(-1 * diff).Date;
        }
    }
    

    然后您可以按一周的第一个日期分组。

    所以这段代码在常规 SQL 中:

    SELECT * From T GROUP BY DATEPART(wk, T.Date)
    

    可以像这样在 Linq to SQL 中完成

    T.GroupBy(i => i.Date.StartOfWeek(DayOfWeek.Monday));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-11-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多