如何使用 DateOnly 和 ef core 查询 SQL Server

mar*_*yyy 5 c# linq sql-server date entity-framework-core

我正在将 .NET 6 和 EF Core 6 与 SQL Server 结合使用,并希望使用新DateOnly类型。

我已经能够使用此转换器读取数据并将数据写入数据库,但是查询表不起作用,因为 Linq 不知道如何翻译DateOnly

转换器注册于DbContext

protected override void ConfigureConventions
(ModelConfigurationBuilder builder)        
{
    builder.Properties<DateOnly>()                
        .HaveConversion<DateOnlyConverter>()                
        .HaveColumnType("date");
    builder.Properties<DateOnly?>()                
        .HaveConversion<NullableDateOnlyConverter>()                
        .HaveColumnType("date");        
}
Run Code Online (Sandbox Code Playgroud)

例子

    public XXXXByDateSpec(DateOnly validFrom)
    {
        Query.Where(x => x.ValidFrom.Year <= validFrom.Year);
    }
Run Code Online (Sandbox Code Playgroud)

但这会导致以下异常。

System.InvalidOperationException:无法翻译 LINQ 表达式 'DbSet().Where(c => c.ValidFrom.Year <= __validFrom_Year_1)'。
以可翻译的形式重写查询,或者通过插入对“AsEnumerable”、“AsAsyncEnumerable”、“ToList”或“ToListAsync”的调用来显式切换到客户端计算。有关详细信息,请参阅https://go.microsoft.com/fwlink/?linkid=2101038 。

当我尝试首先将其解析为DateTime类似错误的结果时。

Query.Where(x => DateTime.Parse(x.ValidFrom.ToString()).Year <= DateTime.Parse(validFrom.ToString()).Year);
Run Code Online (Sandbox Code Playgroud)

System.InvalidOperationException:无法翻译 LINQ 表达式 'DbSet().Where(c => DateTime.Parse(c.ValidFrom.ToString()).Year <= __Parse_Year_0)'。附加信息:方法“object.ToString”的翻译失败。如果此方法可以映射到您的自定义函数,请参阅https://go.microsoft.com/fwlink/?linkid=2132413了解更多信息。
方法“object.ToString”的翻译失败。如果此方法可以映射到您的自定义函数,请参阅https://go.microsoft.com/fwlink/?linkid=2132413了解更多信息。以可翻译的形式重写查询,或者通过插入对“AsEnumerable”、“AsAsyncEnumerable”、“ToList”或“ToListAsync”的调用来显式切换到客户端计算。有关详细信息,请参阅https://go.microsoft.com/fwlink/?linkid=2101038 。

我如何告诉 Linq 执行与 EF Core 相同的操作,并在将代码转换为 SQL 之前进行类型转换DateTime?这可能吗?

或者如何注册ToString()对 Linq 的调用?异常中的链接并不能真正帮助我。

Sti*_*tig 4

这应该可以工作,尽管不那么可读。如果存在索引,这将受益于使用索引。如果仅使用年份部分,则以 DateOnly 作为参数的合同也会令人困惑。

 public XXXXByDateSpec(int year)
 {
    Query.Where(x => x.ValidFrom < new DateOnly(year + 1, 1, 1);
 }
Run Code Online (Sandbox Code Playgroud)

  • 这仅适用于年份。如果将月或日加 1(月 12 + 1)会发生什么? (2认同)