与 EF 核心中的 DateTime 相比,生成的日期字符串具有 6 位小数(以毫秒为单位)

Comparing to DateTime in EF core is generating date string with 6 decimals in milliseconds

我正在做这个查询

var sourceItems = await this.dbContext.Orders
.AsNoTracking()
.Where(item => item.OrderDate > new DateTime(2019, 1, 1))
.Select(order => new
{
    order.CustomerCode
})
.ToListAsync();

我得到这个 sql 查询

SELECT [o].[CustomerCode]
FROM [Order] AS [o]
WHERE [o].[OrderDate] > '2019-01-01T00:00:00.0000000'

失败

Core Microsoft SqlClient Data Provider: Conversion failed when converting date and/or time from character string.

我正在使用 EF Core 3.1.5。

如果我 运行 sql 直接查询,如果我将日期的毫秒部分中的数字从 6 个零减少到 3 个零或更少,它就会起作用。

如何让 EF Core 跳过日期的毫秒部分?

EF Core 从其他操作数推断常量值的提供者类型。在这种特殊情况下,来自 item.OrderDate

文字的格式表明 EF Core 假定 datetime2 提供程序类型(DateTime CLR 类型的默认映射),而异常表明实际列类型是 datetime.

要解决此问题,您必须让 EF Core 知道实际类型,例如将以下内容添加到您的 OnModelCreating 覆盖中:

modelBuilder.Entity<Order>()
    .Property(e => e.OrderDate)
    .HasColumnType("datetime");

现在查询将使用正确的 '2019-01-01T00:00:00.000' 文字。

另一个改进是消除文字并让 EF Core 绑定参数。这是通过将 new DateTime(...) 表达式放入查询表达式树外部的变量中并在内部使用该变量来实现的:

var afterDate = new DateTime(2019, 1, 1); // <--
var sourceItems = await this.dbContext.Orders
    .AsNoTracking()
    .Where(item => item.OrderDate > afterDate) // <--
    .Select(order => new
    {
        order.CustomerCode
    })
    .ToListAsync();