实体框架Code First:DateTime2应该使用哪个DataType属性?

13

在使用Entity Framework Code First时,有时默认约定不能创建所需的数据库类型。例如,默认情况下,类型为System.DateTime的属性会创建一个DateTime类型的数据库列。如果想要它具有datetime2类型(没有时区和夏令时问题的DateTime类型),该怎么办呢?

可以使用数据注释(Data Annotations)来指定所需的数据库类型,其中一个构造函数DataTypeAttribute接受一个DataType枚举参数。因此,可以指定类似以下内容:

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

DataType枚举类型包含很多类型,但是它缺少一个DateTime2的值。

另一种方法是使用Fluent API。在DBContext.OnModelCreating方法中创建DateTime2

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

DataTypeAttribute有一个第二个构造函数,接受一个字符串。该字符串被定义为:

与数据字段关联的自定义字段模板的名称。

因此,人们可能会认为以下内容足以创建datetime2:

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

哎呀,这样不行。创建的列仍然具有DateTime格式。

问题:在构造函数中使用哪个字符串来创建datetime2?

2个回答

31

DataType属性在Code First中不用于列类型映射

Column注释在指定映射列的属性方面更为熟练。您可以规定列的名称、数据类型或甚至出现在表中的顺序。[...] 不要将Column的TypeName属性与DataType DataAnnotation混淆。DataType是用于UI的注释,Code First会忽略它。

因此:

[Column(TypeName="datetime2")] 

2
如何在datetime2类型中定义精度。 - Muhammad Haroon

11

如果您仍然对如何为属性定义列类型感兴趣,则可以从EF版本6.0开始定义某些类型的每个值都应该具有一些数据库类型。

这可以在DbContext.OnModelCreating中使用DbModelBuilder.Properties完成。

如果这样做,您不必为每个DateTime编写属性或流畅的API。更容易保持一致并让所有DateTime具有相同的列类型。同样,您可以为所有小数指定相同的精度,即使将来添加了小数。

假设您要定义每个System.DateTime都应该具有列类型DateTime2;每个System.Decimal都应该具有指定精度的列类型。在DbContext中,您应编写:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    // every property of type DateTime should have a column type of "datetime2":
    modelBuilder.Properties<DateTime>()
      .Configure(property => property.HasColumnType("datetime2"));
    // every property of type decimal should have a precision of 19
    // and a scale of 8:
    modelBuilder.Properties<decimal>()
        .Configure(property => property.HasPrecision(19, 8));
}

1
我认为对于EF的后续版本,您可能需要使用属性的复数形式:modelBuilder.Properties<DateTime>().Configure(property => property.HasColumnType("datetime2")); - emp
1
感谢emp的评论。我已经更新了我的答案以反映这一点。 - Harald Coppoolse

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接