Entity Framework Code First: which DataType attribute for DateTime2?

Harald Coppoolse picture Harald Coppoolse · Nov 3, 2015 · Viewed 12.7k times · Source

Sometime when using Entity Framework Code First, the default conventions do not create the database type you want. For instance by default a property of type System.DateTime creates a database column of type DateTime. What to do if you want it to have a type of datetime2 (the DateTime type that has no problems with time zones and daylight saving time)?

It is possible to specify the required database type with Data Annotations using a DataTypeAtrribute. One of the constructors of DataTypeAttribute accepts a parameter DataType Enumeration. So one could specify something like:

[DataType(DataType.DateTime)]
public DateTime DateOfBirth {get; set;}

The DataType enumeration type contains a lot of types, however it is missing a value for DateTime2.

Another approach would be using Fluent API. Create a DateTime2 in method DBContext.OnModelCreating:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<Student>().Property(p => p.BirthDate)
        .HasColumnType("datetime2");
}

The DataTypeAttribute has a second constructor that accepts a string. This string is defined as

The name of the custom field template to associate with the data field.

So one would assume that the following would be enough to create a datetime2:

[DataType("datetime2")]
public DateTime DateOfBirth {get; set;}

Alas, this doesn't work. The created column still has the DateTime format.

Question: which string to use in the constructor to create a datetime2?

Answer

CodeCaster picture CodeCaster · Nov 3, 2015

The DataType attribute is not used for column type mapping for Code First:

The Column annotation is a more adept in specifying the attributes of a mapped column. You can stipulate a name, data type or even the order in which a column appears in the table. [...] Don’t confuse Column’s TypeName attribute with the DataType DataAnnotation. DataType is an annotation used for the UI and is ignored by code first.

So:

[Column(TypeName="datetime2")]