我的 EF core 和 MariaDb 数据库似乎有问题。首先,我无法对数据库进行明显的更改,因此该选项不可行。
我有一个“联系人”表,其中保存了联系日期。此联系日期以字符串值的形式保存,仅包含日期,例如:2020 年 8 月 30 日为 2020-08-30。 我有一个针对该字段的 EF 核心映射,如下所示:
entity.Property(e => e.ContactDate)
.IsRequired()
.HasColumnName("contactDate")
.HasColumnType("varchar(255)")
其中 e.ContactDate 是 DateTime 属性。
当我在代码中使用该属性时,日期时间按预期工作并包含保存在数据库中的日期。万岁!
然而,当我想查询该日期时间时,问题就出现了。鉴于此查询:
SELECT `c7`.`contactDate`
FROM `contacts` AS `c7`
WHERE (`f`.`uuid` = `c7`.`fileUuid`) AND (`c7`.`numberOfContacts` > 0)
ORDER BY `c7`.`contactDate`
LIMIT 1) <= @__endDate_1) AND (`f`.`closingDate` IS NULL OR ((`f`.`closingDate` >= @__startDate_2)
属性 startDate 和 endDate 作为参数插入到查询中。例如,@__endDate_1='2019-12-31 00:00:00'
。问题就在这里:MySql 将对 contactDate 数据库字段与 endDate 的字符串值进行字符串比较。因为一个有时间字段,而另一个没有,所以如果我想做的不仅仅是函数,我会遇到问题。 (SELECT "2020-02-04">= "2020-02-04 00:00:00"
返回 0)。
有什么办法可以:
- 或者更改 EF,使其在每个查询中将 contactDate 转换为带有时间戳的值
- 或者更改 EF,使其将 DateTime 值转换为不带任何时间值的日期值?
对于我引入新的“Date”类作为 EF 的 DateTime 到 Date 字符串包装器的第三种可能的解决方案,你们有何看法?
谢谢!
最佳答案
与
.HasColumnType("varchar(255)")
您正在激活 EF Core 内置 DateTime to string value converter 。它没有记录,但它使用以下格式(或类似格式)将 DateTime
值(绑定(bind)命令参数时)转换为 string
"yyyy\\-MM\\-dd HH\\:mm\\:ss.FFFFFFF"
而您需要的是这样的格式
"yyyy\\-MM\\-dd"
可以通过configuring a custom value converter来实现:
entity.Property(e => e.ContactDate)
.HasConversion(
value => value.ToString("yyyy\\-MM\\-dd"),
dbValue => DateTime.Parse(dbValue, CultureInfo.InvariantCulture)
)
// the rest is the same
.IsRequired()
.HasColumnName("contactDate")
.HasColumnType("varchar(255)"); // or .IsUnicode(false).HasMaxLength(255)
就是这样。现在,相关参数将是 @__endDate_1='2019-12-31'
,因此这实现了项目符号 #2。
项目符号 #1 是不可能的。
创建特殊的Date
类型怎么样,这是可能的,但并不容易,因为它需要大量的基础设施管道代码。有一些包可以做到这一点 - NodaTime、NetTopology 等。如果您感兴趣,您可以查看它们的实现,但恕我直言,支持(简单)自定义值类型不是 EF Core 优先级(当前),因此在它们获得更好的支持之前,我将留在值(value)转换器。
关于c# - Entity Framework MariaDb 日期作为字符串问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63655418/