如何在EF中执行日期部分比较

Tho*_*mas 6 c# t-sql linq-to-entities entity-framework datetime-comparison

我听说人们说日期时间比较不起作用只是因为时间因素,因为datetime有时间部分.

在SQL中我总是像这样比较日期时间,它工作正常

select * from employee
where convert(varchar,dob,112) > '20111201' // this yyyymmdd format.
Run Code Online (Sandbox Code Playgroud)

我怎么能在LINQ查询中模拟这个?

mcl*_*129 10

如果您使用的是.NET 4或更高版本,请使用EntityFunctions.TruncateTime帮助方法.这会将这种类型的datetime-to-date转换为SQL.

from e in EfEmployeeContext
where EntityFunctions.TruncateTime(e.DOB) > new DateTime(2011,12,01);
Run Code Online (Sandbox Code Playgroud)

  • EntityFunctions.TruncateTime(e.DOB)已过时,batter尝试使用System.Data.Entity.DbFunctions.TruncateTime(e.DOB) (4认同)
  • 如果您正在使用`LINQ to SQL`,那么我会将标签移除到`EntityFramework`和`linq-to-entities`,以及问题标题中对EF的引用.使用LINQ to SQL意味着您的问题变得无关紧要. (3认同)

Kei*_*thS 3

需要记住的一件事是,对表示数据库列的 DateTime 结构的操作不会转换为 SQL。因此,您不能编写如下查询:

from e in EfEmployeeContext
where e.DOB.Date > new DateTime(2011,12,01);
Run Code Online (Sandbox Code Playgroud)

...因为 e.DOB 代表数据库中的 DOB 列,并且 EF 不知道如何转换 Date 子属性。

但是,有一个简单的解决方法,具体取决于您想要的日期:

  • 如果您想要包含出生日期为 12/01/2011 以及该日期之后出生的所有员工,则只需查询:

    from e in EfEmployeeContext
    where e.DOB > new DateTime(2011,12,01);
    
    Run Code Online (Sandbox Code Playgroud)
  • 如果您只想包含 2011 年 12 月 1 日之后出生的员工,则查询:

    from e in EfEmployeeContext
    where e.DOB >= new DateTime(2011,12,02);
    
    Run Code Online (Sandbox Code Playgroud)

简而言之,可以根据需要设置条件,即您要比较的常量或文字日期时间。您无法对 where 谓词中表示数据库列的属性进行根本性修改。这意味着您无法将一个 DateTime 列与另一个 DateTime 列的投影进行比较,例如:

    //get all employees that were hired in the first six months of the year
    from e in EfEmployeeContext
    where e.HireDate < new DateTime(e.HireDate.Year, 7, 1);
Run Code Online (Sandbox Code Playgroud)