EF6 and MySQL timezone support

时间:2017-06-12 16:47:35

标签: c# mysql entity-framework datetime

I am storing datetimes at the UTC format (using DateTime.UtcNow) in a MySQL database. 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.

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. The created dates have their Kind property set to DateTimeKind.Utc and their value set to 08h00 am. In the database, the dates value are 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.

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.

// 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. 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).

Absolutely nothing in my code changes the CreationDate... Before the call to DbContext.SaveChangesAsync(), the CreationDate has the unchanged expected value. 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).

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).

1 个答案:

答案 0 :(得分:0)

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

gtx

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

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

实体框架无法自行更新CreationDate。最后,这与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; 问题无关。为了解决这个问题,我遵循joshp链接中提出的解决方案,但使用了一些improvements