如何使用 EF Core 按周 对数据分组?

Posted dotNET跨平台

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何使用 EF Core 按周 对数据分组?相关的知识,希望对你有一定的参考价值。

咨询区

  • Aza

在 Entity Framework 6 中,我可以用 SqlFunctions.DatePart() 函数来实现,参考如下代码:

var byWeek = data.GroupBy(x => SqlFunctions.DatePart("week", x.Date));

现在的问题是, Entity Framework Core 中不提供如 DbFunctionsSqlFunctions 方法,这就很尴尬了,请问我该如何解决呢?

回答区

  • cyptus

既然没有现成的函数,可以自己实现一个,将 sql 中的 datepart 方法用 C# 中的 DbFunctionAttribute 给标注上,这样做的好处是告诉 efcore 不要去以 string 方式处理 detepart 参数,参考代码如下:

DbContext:

public int? DatePart(string datePartArg, DateTime? date) => throw new Exception();

public void OnModelCreating(DbModelBuilder modelBuilder)
{
    var methodInfo = typeof(DbContext).GetRuntimeMethod(nameof(DatePart), new[] { typeof(string), typeof(DateTime) });
    modelBuilder.HasDbFunction(methodInfo)
                .HasTranslation(args => new SqlFunctionExpression(nameof(DatePart), typeof(int?), new[]
                {
                        new SqlFragmentExpression(args.ToArray()[0].ToString()), args.ToArray()[1]
                }));
}

查询方式:

repository.GroupBy(x => dbContext.DatePart("week", x.CreatedAt));

更多信息参考 github:https://github.com/aspnet/EntityFrameworkCore/issues/10404

  • Nikolay Kostov

确实有些麻烦,我现在的变通方法是除7实现,首先自定义个方法,代码如下:

private DateTime GetFirstMondayOfYear(int year)
{
    var dt = new DateTime(year, 1, 1);
    while (dt.DayOfWeek != DayOfWeek.Monday)
    {
        dt = dt.AddDays(1);
    }

    return dt;
}

然后在分组的时候计算。

var firstMondayOfYear = this.GetFirstMondayOfYear(DateTime.Now.Year);

var entries = this.entitiesService.FindForLastMonths(this.CurrentUser.Id, 6)
                        .GroupBy(x => ((int)(x.Date - firstMondayOfYear).TotalDays / 7))

这个分组会得到当前年的周个数,负值是表示挂在前一年的, 之后就可以通过下面的属性方法得到当前的周名称。

public string WeekName
{
    get
    {
        var year = DateTime.Now.AddYears((int)Math.Floor(this.WeekNumber / 52.0)).Year;
        var weekNumber = this.WeekNumber % 52;
        
        while (weekNumber < 0)
        {
            weekNumber += 52;
        }

        return $"{year}, W{weekNumber}";
    }
}

点评区

sql处理稍微复杂一点,用ef处理起来还是有些麻烦的,没啥好说的,学习了。

以上是关于如何使用 EF Core 按周 对数据分组?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Django ORM 按周分组

SQL Server 按过去 24 小时、上周和上个月对促销进行分组,并按周降序排序

如何在打字稿/离子2中按周分组时间戳?

按周分组,如何获得空周?

EF Core 3.1 (LINQ) - 如何在多列上左加入和分组

按周分组和求和