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?
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")]