Handling MySQL Zero Date with EF Core

可紊 提交于 2021-01-27 06:36:26

问题


Background: I have 200+ legacy VB6 apps which I am converting to C#, using EntityFramework Core as our ORM. Unfortunately a lot of the apps utilize MySQL's zero date (0000-00-00). So I need to cater for this and be able to store a zero date in some way. Changing the fundamental way this works in the 200+ apps is not currently an option.

Setup: I can define an entity property which represents the field definition in MySQL eg:

 public DateTime ExpiryDate { get; set; }

...

 entity.Property(e => e.ExpiryDate)
                       .IsRequired()
                       .HasColumnType("datetime")
                       .HasDefaultValueSql("'0000-00-00 00:00:00'");

This will correctly store a zero date if no value is sent on an insert.

Problem: Because C# has a minimum date of 0001-01-01 it is not possible for me to explicitly store a zero date. So my question is... Is there a way to set up my entities to get this zero date into and out of the database??

So far: I have tried using a backing field, defined as a string so that I can manipulate any DateTime.MinValue to become '0000-00-00'. This allows me to store the zero date but then causes a casting issue (as you would expect) when trying to retrieve the data:

System.InvalidCastException : Unable to cast object of type 'System.DateTime' to type 'System.String'.

Current packages I am using are:

  • EFCore 1.1
  • PomeloEntityFrameWorkCore 1.1.2
  • MySQL 5.7.18

回答1:


People might argue that this is better suited as a comment, but basically, it's to long for that.

And:

You'll have to help me out a bit since I don't have a working system at hand, so I am doing this from the top of my head. (and I am in a bit of a rush)

First, start out with a not mapped property:

[NotMapped]
public DateTime ExpiryDate { get; set; }

This property is not mapped. It might lead to some errors concerning the database does not match the model, but we can overcome that. This property will not be automatically filled when querying the data. So, we need a way to deal with this our self.

For example, (which is a bad example because we need the context in the entity somewhere):

[NotMapped]
public DateTime? ExpiryDate 
{
    get
    {
         //of course you'll need some caching here
         var s = context.Database.SqlQuery<string>("query to select datetime as string");
         //additional logic to determine validity:
         if (s == "0000-00-00")
             return null;
         //else:
         //do the conversion
    }
 }

The basic question here; how far do you want to go to support this within EF framework? Do you only need to read it, or write as well, using the change tracker of EF etc.?

There are other posibilities, for example, to perform a perform a CAST to nvarchar within the SQL itself to obtain the data and further process it.

Maybe the ModelBuilder exposes some additional options.



来源:https://stackoverflow.com/questions/45959778/handling-mysql-zero-date-with-ef-core

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!