在代码优先实体框架和SQL Server中使用DateTime属性

Cha*_*evy 27 datetime entity-framework-4 ef-code-first

我有一个示例类book:

public class Book
{
    [Key]
    public int Id { get; set; }
    public string Name { get; set; }
    public DateTime DateAdded { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

当我尝试bookBookDb上下文中添加新内容时...

using (BookDb db = new BookDb())
{
    Book book = new Book {
        Name = "Some name",
        DateAdded = DateTime.Now
    };

    db.Books.Add(book);
    db.SaveChanges();
}
Run Code Online (Sandbox Code Playgroud)

...抛出错误:

System.Data.SqlClient.SqlException:将datetime2数据类型转换为日期时间数据类型会导致超出范围的值.该语句已终止.


我发现原因是datetime.NET和SQL Server之间不兼容的类型.有一种方法可以告诉EF在传统的实体框架中使用SQL Server的格式,但我如何在Code-First Entity Framework中执行此操作?

我在.NET 4(MVC 3 Web应用程序)和SQL Server 2008 Express上使用EF4.

Sla*_*uma 49

您可以在Fluent API中指定类型:

modelBuilder.Entity<Book>()
    .Property(f => f.DateTimeAdded)
    .HasColumnType("datetime2");
Run Code Online (Sandbox Code Playgroud)

这将datetime2(7)在数据库中创建一个列.如果您想微调您可以使用的精度:

modelBuilder.Entity<Book>()
    .Property(f => f.DateTimeAdded)
    .HasColumnType("datetime2")
    .HasPrecision(0);
Run Code Online (Sandbox Code Playgroud)

...对于datetime2(0)DB中的列.

但是,您在问题中显示的代码是有效的,因为该datetime类型允许将日期存储回1750年左右.例外情况仅发生在较早的日期.此异常的常见原因是未初始化的DateTime属性,因为它表示年份0001,无法存储datetime在SQL Server 的列中.

没有相应的属性可以使用数据注释来定义它.它只能使用Fluent API.


Hou*_*man 30

保存日期时,需要填充值.这就是为什么你得到这个错误.

只是用DateTime?.上面没有必要使用魔法.

  • 如果那是您在模型中想要的类型,请使用可为空的类型,但如果不这样做,则不应仅使用它来使您的种子或其他初始化程序起作用。 (2认同)

str*_*ics 23

您可以使用datetime2类型注释类的属性.

public class Book
{
    [Column(TypeName = "datetime2")]
    public DateTime DateAdded { get; set; }
}
Run Code Online (Sandbox Code Playgroud)