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

时间:2012-03-08 22:55:21

标签: c# .net linq datetime

我有

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

但它比较了DateTime的时间部分。我真的不需要它。

如果没有时间怎么办?

谢谢!

9 个答案:

答案 0 :(得分:92)

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);

答案 1 :(得分:65)

只需使用Date属性:

var today = DateTime.Today;

var q = db.Games.Where(t => t.StartDate.Date >= today)
                .OrderBy(t => t.StartDate);

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

Entry 1: March 8th, 8am
Entry 2: March 10th, 10pm
Entry 3: March 8th, 5am
Entry 4: March 9th, 8pm

当然,两个条目1和3都应该在结果中,或它们都不应该......但是如果你评估DateTime.Today并且它< em>更改到执行前两次检查后的3月9日,最终可能会有条目1,2,4。

当然,使用DateTime.Today假设您对本地时区中的日期感兴趣。这可能不合适,你应该绝对确定你知道你的意思。例如,可能想要使用DateTime.UtcNow.Date。不幸的是,DateTime is a slippery beast ...

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

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

答案 2 :(得分:20)

试试此代码

var today = DateTime.Today;
var q = db.Games.Where(t => DbFunctions.TruncateTime(t.StartDate) <= today);

答案 3 :(得分: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));

我不明白为什么Jon的解决方案无效......

答案 4 :(得分: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进行比较的任何日期时间都将安全返回。除非你想在同一天进行字面比较,在这种情况下,我认为你应该选择Caesar的答案。

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

答案 5 :(得分:2)

.Date的答案具有误导性,因为您遇到了前面提到的错误。除了提到的DbFunctions.TruncateTime外,另一种比较方式可能是:

DateTime today = DateTime.Now.date;
var q = db.Games.Where(t => SqlFunctions.DateDiff("dayofyear", today, t.StartDate) <= 0
      && SqlFunctions.DateDiff("year", today, t.StartDate) <= 0)

在生成的SQL查询中看起来更好(更易读)。但是我承认在C#代码XD中看起来更糟。我正在测试某些东西,但是TruncateTime似乎对我不起作用,不幸的是故障出在键盘和椅子之间,但与此同时,我找到了这种选择。

答案 6 :(得分:1)

尝试

var q = db.Games.Where(t => t.StartDate.Date >= DateTime.Now.Date).OrderBy(d => d.StartDate);

答案 7 :(得分:1)

DateTime dt=DateTime.Now.date;

var q = db.Games.Where(
    t =>EntityFunction.TruncateTime(t.StartDate.Date >=EntityFunction.TruncateTime(dt)).OrderBy(d => d.StartDate
);

答案 8 :(得分:1)

当我遇到相同的查询时,我发现了这个问题。我终于找到它而不使用DbFunctions。 试试这个:

  

var q = db.Games.Where(t => t.StartDate.Day == DateTime.Now.Day && t.StartDate.Month == DateTime.Now.Month && t.StartDate.Year == DateTime。 Now.Year).OrderBy(d => d.StartDate);

通过分叉日期部分,我们可以有效地仅比较日期,从而节省了时间。

希望有帮助。请原谅我的答案格式,这是我的第一个答案。