简体   繁体   English

EF6和MySQL时区支持

[英]EF6 and MySQL timezone support

I am storing datetimes at the UTC format (using DateTime.UtcNow ) in a MySQL database. 我将日期时间以UTC格式(使用DateTime.UtcNow )存储在MySQL数据库中。 After some manipulations of the entity containing that dates, it becomes a mess. 在对包含该日期的实体进行一些操作之后,它变得一团糟。

Here is how I defined my table: 这是我定义表格的方式:

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

I am running the framework .NET 4.5.2 and I mapped my database with Entity Framework 6 and Database first principle. 我正在运行.NET 4.5.2框架,并使用Entity Framework 6Database first原则映射了数据库。

Here is what I am doing: 这是我在做什么:

First step, create the object: 第一步,创建对象:

var now = DateTime.UtcNow;
var globalVersion = new GlobalVersion
{
    CreationDate = now,
    LastUpdateDate = now
};
// saving the object

Let's say it is 10:00 am in my country and I am GMT +2 . 假设我的国家/地区是10:00 amGMT +2 The created dates have their Kind property set to DateTimeKind.Utc and their value set to 08h00 am. 创建的日期将其Kind属性设置为DateTimeKind.Utc并将其值设置为08h00 am。 In the database, the dates value are 08:00 am. 在数据库中,日期值为08:00 am。

Everything is fine. 一切顺利。

Second step, get the object: 第二步,获取对象:

Using another connection, when I get the object from the database, the date are set to 08:00 am but their Kind property are set to DateTimeKind.Local. 使用另一个连接,当我从数据库中获取对象时,日期设置为上午08:00,但其Kind属性设置为DateTimeKind.Local。

This is not totally fine, but while I am only reading the data, this is not a problem. 这不是完全可以的,但是虽然我只读取数据,但这不是问题。 I did not even notice it until I need to change one date. 我什至没有注意到它,直到我需要更改一个日期。

Updating one date: 更新一个日期:

And here comes the mess. 一团糟。 At one moment, I need to change only one date. 在一瞬间,我只需要更改一个日期。 Let's say it is now 11:00 am in my country. 假设现在11:00 am我国家的11:00 am

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

Once saved, the LastUpdateDate is set to 09:00 am in the database (which is fine) but the CreationDate is now set to... 11:00 am . 保存后, LastUpdateDate在数据库中设置为09:00 am (可以),但是CreationDate现在设置为... 11:00 am It looks like it is set to DateTime.Now at the DbContext.SaveChangesAsync() (I am saying that because if I pause during the debug between the DateTime.UtcNow and the SaveChangesAsync instruction, the CreationDate is set to the moment I click on continue). 它看起来像是在DbContext.SaveChangesAsync()处设置为DateTime.Now (我说这是因为,如果在调试期间在DateTime.UtcNowSaveChangesAsync指令之间暂停,则CreationDate会设置为我单击继续的那一刻)。

Absolutely nothing in my code changes the CreationDate... Before the call to DbContext.SaveChangesAsync() , the CreationDate has the unchanged expected value. 在我的代码中,绝对没有任何东西可以更改CreationDate ...在调用DbContext.SaveChangesAsync()CreationDate具有不变的期望值。 Right after, the CreationDate is set to the moment I clicked on continue (only in the database, in the EF cache, the value is still the same, but at the next connection, if will take the value in the database). 紧接着, CreationDate设置为我单击“继续”的那一刻(仅在数据库中,在EF高速缓存中,该值仍然相同,但是在下一次连接时,如果将在数据库中使用该值)。

I am absolutely lost with this behavior... What could cause that? 我对这种行为完全迷失了……是什么原因引起的?

I am writing the same operations in parallel in a SQLite database (I set the DateTimeKind to Utc in the connection string, and I do not have the problem). 我正在SQLite数据库中并行编写相同的操作(我在连接字符串中将DateTimeKind设置为Utc ,但没有问题)。

Wow... though I was creating my table with this script: 哇...虽然我正在用此脚本创建表:

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

MySQL Workbench (or MySQL ?) actually created a table like that (get it using the MySQL Workbench reverse engineering): 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;

It had no sense that Entity Framework update the CreationDate on his own. 实体框架自己更新CreationDate毫无意义。 Finally, this as nothing to do with the DateTimeKind issue. 最后,这与DateTimeKind问题无关。 To solved it, I follow the solution proposed in the joshp's link but with some improvements . 为了解决这个问题,我遵循了joshp链接中提出的解决方案,但进行了一些改进

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM