I\'m using the DbContext and Code First APIs introduced with Entity Framework 4.1.
The data model uses basic data types such as string
Even though this question is quite old and there are great answers already, I thought I should put one more which explains 3 different approaches to solve this problem.
1st Approach
Explicitly map DateTime
property public virtual DateTime Start { get; set; }
to datetime2
in corresponding column in the table. Because by default EF will map it to datetime
.
This can be done by fluent API or data annotation.
Fluent API
In DbContext class overide OnModelCreating
and configure property Start
(for explanation reasons it's a property of EntityClass class).
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
//Configure only one property
modelBuilder.Entity<EntityClass>()
.Property(e => e.Start)
.HasColumnType("datetime2");
//or configure all DateTime Preperties globally(EF 6 and Above)
modelBuilder.Properties<DateTime>()
.Configure(c => c.HasColumnType("datetime2"));
}
Data annotation
[Column(TypeName="datetime2")]
public virtual DateTime Start { get; set; }
2nd Approach
Initialize Start
to a default value in EntityClass constructor.This is good as if for some reason the value of Start
is not set before saving the entity into the database start will always have a default value. Make sure default value is greater than or equal to SqlDateTime.MinValue ( from January 1, 1753 to December 31, 9999)
public class EntityClass
{
public EntityClass()
{
Start= DateTime.Now;
}
public DateTime Start{ get; set; }
}
3rd Approach
Make Start
to be of type nullable DateTime
-note ?
after DateTime
-
public virtual DateTime? Start { get; set; }
For more explanation read this post
In some cases, DateTime.MinValue
(or equivalenly, default(DateTime)
) is used to indicate an unknown value.
This simple extension method can help handle such situations:
public static class DbDateHelper
{
/// <summary>
/// Replaces any date before 01.01.1753 with a Nullable of
/// DateTime with a value of null.
/// </summary>
/// <param name="date">Date to check</param>
/// <returns>Input date if valid in the DB, or Null if date is
/// too early to be DB compatible.</returns>
public static DateTime? ToNullIfTooEarlyForDb(this DateTime date)
{
return (date >= (DateTime) SqlDateTime.MinValue) ? date : (DateTime?)null;
}
}
Usage:
DateTime? dateToPassOnToDb = tooEarlyDate.ToNullIfTooEarlyForDb();
One line fixes this:
modelBuilder.Properties<DateTime>().Configure(c => c.HasColumnType("datetime2"));
So, in my code, I added:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Properties<DateTime>().Configure(c => c.HasColumnType("datetime2"));
}
Adding that one line to the DBContext subclass override void OnModelCreating section should work.