如何在 Entity Framework Core 中按周分组?

问题描述 投票:0回答:4

在Entity Framework 6中我可以使用

SqlFunctions.DatePart()
方法:

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

但是这些类(

DbFunctions
SqlFunctions
在 Entity Framework Core 中不可用)(参考)。

所以我的问题是如何在实体框架核心中按周分组?

linq group-by .net-core entity-framework-core week-number
4个回答
3
投票

我目前针对缺失功能的解决方法是

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

功能

GetFirstMondayOfYear

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

    return dt;
}

此分组给出了当年的周数和前几年的负值。

稍后您可以使用此 getter 获取周名称:

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}";
    }
}

2
投票

可以通过用 DbFunctionAttribute 包装来使用 datepart SQL 函数。 棘手的部分是告诉 ef core 不要将 datepart 类型参数作为字符串处理。示例:

数据库上下文:

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));

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


0
投票

我碰巧已经在使用视图,因此我只是向该视图添加了代表周、月和年的额外列 - 以便通过 EF Core 轻松分组。

OrderDateDt,
DATEPART(week, OrderDateDt) OrderDateDt_Week,
DATEPART(month, OrderDateDt) OrderDateDt_Month,
DATEPART(year, OrderDateDt) OrderDateDt_Year,

0
投票

我们创建了一个表,其中每个日期包含一行加上相应的 iso_week。现在您可以按 iso_week 列加入日期和分组

© www.soinside.com 2019 - 2024. All rights reserved.