EF6 和 MySQL 时区支持

Posted

技术标签:

【中文标题】EF6 和 MySQL 时区支持【英文标题】:EF6 and MySQL timezone support 【发布时间】:2017-11-14 05:45:17 【问题描述】:

我将日期时间以 UTC 格式(使用 DateTime.UtcNow)存储在 mysql 数据库中。在对包含该日期的实体进行一些操作后,它变得一团糟。

这是我定义表格的方式:

CREATE TABLE `gsrep`.`GlobalVersion` (
  [..],
  `CreationDate` TIMESTAMP NOT NULL,
  `LastUpdateDate` TIMESTAMP NOT NULL,
  [..]
);

我正在运行框架 .NET 4.5.2,并使用 Entity Framework 6Database first 原则映射我的数据库。

这是我正在做的:

第一步,创建对象:

var now = DateTime.UtcNow;
var globalVersion = new GlobalVersion

    CreationDate = now,
    LastUpdateDate = now
;
// saving the object

假设在我的国家是10:00 am,我是GMT +2。创建的日期将其Kind 属性设置为DateTimeKind.Utc,并将其值设置为上午08:00。在数据库中,日期值为上午 08:00。

一切都很好。

第二步,获取对象:

使用另一个连接,当我从数据库中获取对象时,日期设置为上午 08:00,但它们的 Kind 属性设置为 DateTimeKind.Local。

这并不完全没问题,但当我只是读取数据时,这不是问题。我什至没有注意到它,直到我需要更改一个日期。

更新一个日期:

这里是一团糟。在某一时刻,我只需要更改一个日期。假设现在在我的国家/地区是11:00 am

// getting the object
globalVersion.LastUpdateDate = DateTime.UtcNow;
// saving the object

保存后,LastUpdateDate 在数据库中设置为09:00 am(这很好),但CreationDate 现在设置为...11:00 am。看起来它在DbContext.SaveChangesAsync() 处设置为DateTime.Now(我是说因为如果我在DateTime.UtcNowSaveChangesAsync 指令之间的调试期间暂停,CreationDate 设置为我单击继续的那一刻)。

在我的代码中绝对没有改变 CreationDate... 在调用 DbContext.SaveChangesAsync() 之前,CreationDate 的预期值不变。紧接着,CreationDate 设置为我点击继续的那一刻(仅在数据库中,在 EF 缓存中,值仍然相同,但在下一次连接时,如果将取数据库中的值)。

我完全被这种行为迷惑了……是什么原因造成的?

我在 SQLite 数据库中并行编写相同的操作(我在连接字符串中将DateTimeKind 设置为Utc,我没有遇到问题)。

【问题讨论】:

根据您的描述,听起来 EF 在检索时忽略了 mysql 时间戳的 UTC 偏移量,然后甚至更新了您没有更改的字段。可能的提示:***.com/questions/6931014/… @joshp 链接中提供的解决方案修复了DateTime.Kind,但在SaveChangesAsync 期间仍会覆盖 CreationDate ... 【参考方案1】:

哇...虽然我是用这个脚本创建我的表:

CREATE TABLE `gsrep`.`GlobalVersion` (
  [..],
  `CreationDate` TIMESTAMP NOT NULL,
  `LastUpdateDate` TIMESTAMP NOT NULL,
  [..]
);

MySQL Workbench(或 MySQL ?)实际上创建了一个类似的表(使用 MySQL Workbench 逆向工程获取它):

CREATE TABLE `GlobalVersion` (
  [..],
  `CreationDate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `LastUpdateDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
  [..]
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

Entity Framework 自己更新 CreationDate 是没有意义的。最后,这与DateTimeKind 问题无关。为了解决它,我遵循了 joshp 链接中提出的解决方案,但使用了一些 improvements。

【讨论】:

以上是关于EF6 和 MySQL 时区支持的主要内容,如果未能解决你的问题,请参考以下文章

在Visual studio 2017中使用EF6连接MySQL

TIDB 时区支持

在 EF6 Code First 中支持表值函数吗?

EF6不支持sqlite Code First解决方案

从 phpMyAdmin 更改 mysql 时区

数据库时区问题