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 6
和 Database 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.UtcNow
和SaveChangesAsync
指令之间的调试期间暂停,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 时区支持的主要内容,如果未能解决你的问题,请参考以下文章