【问题标题】:Convert sql statement to linq - using datepart and grouping将 sql 语句转换为 linq - 使用 datepart 和分组
【发布时间】:2014-06-11 19:16:04
【问题描述】:

下面的 SQL 返回按周更新的记录计数。
我在 linq 中重新创建了按周返回计数的部分(如下),但我无法获得 startofweekendofweek 列。帮助

SQL

select 
DATEPART(wk, audit_date) week, 
count(audit_date) updatedRec, 

dateadd (week, DATEPART(wk, audit_date),  dateadd (year, DATEPART(year, audit_date)-1900, 0)) - 4 -  datepart(dw, dateadd (week, DATEPART(wk, audit_date),  dateadd (year, DATEPART(year, audit_date)-1900, 0)) - 4) + 1 startofweek,


dateadd (week, DATEPART(wk, audit_date), dateadd (year, DATEPART(year, audit_date)-1900, 0)) - 4 - datepart(dw, dateadd (week, DATEPART(wk, audit_date), dateadd (year, DATEPART(year, audit_date)-1900, 0)) - 4) + 7 endofweek

from itims.Listings_Audit
where audit_type = 'U' and datepart(year,audit_date) = '2014'
Group by DATEPART(wk, audit_date),  DATEPART(year, audit_date)
order by startofweek, week

Linq

    var data = (from p in _db.Listings_Audit
            where p.audit_type == "U"
            where p.audit_date.Value.Year == 2014
            group p by new
            {
                Column1 = (int?) SqlFunctions.DatePart("wk", p.audit_date),
                Column2 = (int?) SqlFunctions.DatePart("year", p.audit_date)
            }
            into g
            select new
            {
                week = g.Key.Column1,
                updatedRecCnt = g.Count(p => p.audit_date != null),


            }).OrderBy(g=>g.week).ToList();

【问题讨论】:

  • 附带说明,这些查询将尽可能慢。您的 wheregroup by 语句不是 Sargable
  • 当您使用LINQ查询DB时,您必须告诉我们您正在使用的具体技术,例如LINQ2SQLLINQ2Entities
  • @HamletHakobyan 由于 OP 使用的是 SqlFunctions 这需要 Linq2Entities
  • @arserbin3,真的吗?我看到很多开发人员尝试将SqlFunctionsLINQ2SQL 或类似的东西一起使用。

标签: c# sql linq linq-to-entities


【解决方案1】:

此 Linq2Entities 查询将为您提供 startofweekendofweek。但是,对于大型列表,您可能会在此类计算中看到性能问题。

这利用EntityFunctions.CreateDateTime 来计算基于年和周的日期。

Linq 查询:

var data = (
    from p in _db.Listings_Audit
    group p by
        new
        {
            Column1 = (int)SqlFunctions.DatePart("wk", p.audit_date),
            Column2 = (int)SqlFunctions.DatePart("year", p.audit_date)
        }
    into g
    select
        new
        {
            week = g.Key.Column1,
            year = g.Key.Column2,
            startOfWeek =
                EntityFunctions.AddDays(
                    EntityFunctions.CreateDateTime(g.Key.Column2, 1, 1, 0, 0, 0),
                    (7 * (g.Key.Column1 - 1))),
            endOfWeek =
                EntityFunctions.AddDays(
                    EntityFunctions.CreateDateTime(g.Key.Column2, 1, 1, 0, 0, 0),
                    (7 * (g.Key.Column1))),
            updatedRecCnt = g.Count(p => p.CreatedDate != null),
        }).OrderBy(g => g.startOfWeek).ToList();
  • 注意:如果您的行包含null 日期,您将需要使用GetValueOrDefault()。但是,根据您将其限制为 "2014" 的示例,这对您来说应该不是问题。

【讨论】:

    【解决方案2】:

    一位朋友给了我我需要的答案。结果与我的 sql 输出相匹配。

    var data = (from p in _db.Listings_Audit
                        where p.audit_type == "U"
                        where p.audit_date.Value.Year == 2014
                        group p by new
                        {
                            Column1 = (int?)SqlFunctions.DatePart("wk", p.audit_date),
                            Column2 = (int?)SqlFunctions.DatePart("year", p.audit_date)
                        }
                            into g
                            select new
                            {
                                week = g.Key.Column1,
                                updatedRecCnt = g.Count(p => p.audit_date != null),
                                year = g.Key.Column2
    
                            }).OrderBy(g => g.week).ToList().Select(y => new
                {
                    week = y.week,
                    y.updatedRecCnt,
                    startofweek = new DateTime(y.year.Value, 1, 1).AddDays(-(int)new DateTime(y.year.Value, 1, 1).DayOfWeek).AddDays(y.week.Value * 7 - 7),
                    endofweek = new DateTime(y.year.Value, 1, 1).AddDays(y.week.Value * 7 - 1).AddDays(-(int)new DateTime(y.year.Value, 1, 1).DayOfWeek)
                });
    

    【讨论】:

      猜你喜欢
      • 2013-02-15
      • 1970-01-01
      • 2023-03-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-29
      • 1970-01-01
      相关资源
      最近更新 更多