Handling MySQL Zero Date with EF Core

c# entity-framework entity-framework-core mysql

Question

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
4
8/31/2017 2:11:34 PM

Popular Answer

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.

0
8/31/2017 9:19:28 AM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow