如何通过LINQ比较DateTime没有时间?

Dev*_*per 54 .net c# linq datetime

我有

var q = db.Games.Where(t => t.StartDate >= DateTime.Now).OrderBy(d => d.StartDate);
Run Code Online (Sandbox Code Playgroud)

但它比较包括时间部分DateTime.我真的不需要它.

如果没有时间怎么办?

谢谢!

Dua*_*iot 95

LINQ to Entities不支持Date属性 - 如果您尝试在LINQ to Entities查询中的DateTime字段上使用它,则会出现错误.但是,您可以使用DbFunctions.TruncateTime方法修剪日期.

var today = DateTime.Today;
var q = db.Games.Where(t => DbFunctions.TruncateTime(t.StartDate) >= today);
Run Code Online (Sandbox Code Playgroud)

  • 只是注意,在实体框架的更高版本中,`EntityFunctions`现在已被`DbFunctions`取代 (15认同)
  • 当MySql DB支持时,这不起作用. (2认同)

Jon*_*eet 71

只需使用该Date属性:

var today = DateTime.Today;

var q = db.Games.Where(t => t.StartDate.Date >= today)
                .OrderBy(t => t.StartDate);
Run Code Online (Sandbox Code Playgroud)

请注意,我已经显式评估DateTime.Today 过一次,以便查询是一致的 - 否则每次执行查询时,甚至执行过程中,Today都可能会发生变化,因此您会得到不一致的结果.例如,假设您有以下数据:

Entry 1: March 8th, 8am
Entry 2: March 10th, 10pm
Entry 3: March 8th, 5am
Entry 4: March 9th, 8pm
Run Code Online (Sandbox Code Playgroud)

当然无论是两个条目1和3应该是结果,或者没有人应该...但如果你评估DateTime.Today改变它执行的第一个两次检查后,3月9日,你可以用条目1,2,4落得.

当然,使用DateTime.Today假设您对当地时区的日期感兴趣.这可能不合适,你应该绝对确定你知道你的意思.例如,您可能想要使用DateTime.UtcNow.Date.不幸的是,这DateTime是一只滑溜溜的野兽 ......

编辑:您可能还想完全摆脱对DateTime静态属性的调用- 它们使代码难以进行单元测试.在Noda Time中,我们有一个专门用于此目的的接口(IClock),我们期望它们被适当地注入.有一个用于生产的"系统时间"实现和用于测试的"存根"实现,或者您可以自己实现它.

当然,您可以在不使用Noda Time的情况下使用相同的想法.要对这段特殊代码进行单元测试,您可能希望将日期传递给它,但是您将从某个地方获取它- 并且注入时钟意味着您可以测试所有代码.

  • LINQ to Entities不支持指定的类型成员"Date".仅支持初始值设定项,实体成员和实体导航属性. (14认同)
  • @SAR:MVC 部分无关紧要,“在 LINQ 中”太模糊了:您特指“在实体框架中”。快速搜索发现 h​​ttp://stackoverflow.com/questions/13539224 - 听起来你想要`EntityFunctions.TruncateTime`。 (2认同)

Cag*_*das 20

试试这个代码

var today = DateTime.Today;
var q = db.Games.Where(t => DbFunctions.TruncateTime(t.StartDate) <= today);
Run Code Online (Sandbox Code Playgroud)


Cae*_*sar 9

我发现在我的情况下,这是唯一的工作方式:(在我的应用程序中,我想删除旧的日志条目)

 var filterDate = dtRemoveLogs.SelectedDate.Value.Date;
 var loadOp = context.Load<ApplicationLog>(context.GetApplicationLogsQuery()
              .Where(l => l.DateTime.Year <= filterDate.Year
                       && l.DateTime.Month <= filterDate.Month
                       && l.DateTime.Day <= filterDate.Day));
Run Code Online (Sandbox Code Playgroud)

我不明白为什么乔恩的解决方案不起作用....


小智 9

碰巧LINQ不喜欢像DateTime.Date.它只是无法转换为SQL查询.所以我想出了一种比较日期的方法,使用Jon的答案,但没有那个顽皮DateTime.Date.像这样的东西:

var q = db.Games.Where(t => t.StartDate.CompareTo(DateTime.Today) >= 0).OrderBy(d => d.StartDate);

这样,我们将完整的数据库DateTime与所有日期和时间的东西进行比较,比如2015-03-04 11:49:45.000或类似的东西,其中DateTime代表当天的实际第一毫秒,如2015-03-04 00:00:00.0000

DateTime.Today如果该日期稍晚或相同,我们与之比较的任何DateTime都将安全返回我们.除非你想在同一天进行字面比较,在这种情况下,我认为你应该选择Caesar的答案.

该方法DateTime.CompareTo()只是花哨的面向对象的东西.如果参数早于您引用的DateTime,则返回-1;如果它是LITERALLY EQUAL(包含所有那些时间的东西),则返回0;如果参数更晚,则返回1.