在 DateTime 比较期间,如何强制实体框架使用 datetime 而不是 datetime2?

hya*_*kov 5 c# sql-server datetime entity-framework

我正在使用实体框架来检索记录,其中一个过滤器是 by datetime

它生成如下查询:

([Extent1].[TxnDateTime] >= convert(datetime2, '2015-02-21 00:00:00.0000000', 121)) 
AND ([Extent1].[TxnDateTime] <= convert(datetime2, '2017-02-21 23:59:59.9999999', 121))
Run Code Online (Sandbox Code Playgroud)

有没有办法让 EF 转换为datetime而不是datetime2?看起来快多了。

我希望 EF 生成这个:

[Extent1].[TxnDateTime] >= convert(datetime, '21/02/2015')  
AND [Extent1].[TxnDateTime] <= convert(datetime, '21/02/2017')
Run Code Online (Sandbox Code Playgroud)

datetime

CPU 时间 = 1234 毫秒,运行时间 = 1250 毫秒。

datetime2

CPU 时间 = 1625 毫秒,运行时间 = 1645 毫秒。

我知道 .NETDateTime类型映射到 SQL Server datetime2。我有什么选择呢?

该列可为空datetime,我将其与DateTime?

Har*_*lse 5

嗯,有趣!当我使用带有列的表创建一个简单的数据库模型时DateTime,实体框架默认创建一个具有 SQL DateTime 类型的列,而不是 DateTime2。我使用EntityFramework版本6.1.3

class Blog
{
     public int Id {get; set;}
     public DateTime IntroductionDate {get; set;}
}
Run Code Online (Sandbox Code Playgroud)

Sql Server Management Studio 报告该列IntrdductionDate具有属性(datetime, not null)

不管怎样,不久前我遇到了一个问题,我希望每个 DateTime 都被建模为 adateTime2而不是datetime. 我想你可以使用类似的方法来强制列使用datetime

class MyDbContext : DbContext
{
    DbSet<...> ...

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
         // Configure that all used DateTime should be modeled datetime2:
         const string standardDateTimeType = "datetime2";
         modelBuilder.Properties<DateTime>()
             .Configure(p => p.HasColumnType(standardDateTimeType);
         ...
    }
Run Code Online (Sandbox Code Playgroud)

您可以将其用于您想要建模的所有类型。例如,如果您想建模所有小数都具有相同的精度和小数位数:

byte standardDecimalPrecision = 19;
byte standardDecimalScale = 8;
modelBuilder.Properties<decimal>()
    .Configure(p => p.HasPrecision(standardDecimalPrecision, standardDecimalScale));
Run Code Online (Sandbox Code Playgroud)

当然,您可以使用数据注释来设置列的类型ColumnAttribute,但这将迫使您为每个 DateTime 执行此操作,并且可能会出现未来的类会忘记这一点的错误。