如何通过 LINQ 比较没有时间的日期时间?

是的

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

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

没有时间怎么做

谢谢!

143090 次浏览

只需使用 DateTime.Today属性获取当前日期。在这种情况下,没有必要截断 t.StartDate(这样做可能会导致性能损失)。

var today = DateTime.Today;


var q = db.Games.Where(t => t.StartDate >= 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改变进行评估,直到3月9日,您可能会得到条目1、2、4。

当然,使用 DateTime.Today假设您对 本地时区的日期感兴趣。这可能是不合适的,你应该让 当然确保你知道你的意思。例如,希望使用 DateTime.UtcNow.Date。不幸的是,DateTime是一只狡猾的野兽..。

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

当然,你可以使用同样的想法而不用使用 Noda Time。为了单元测试这段特定的代码,您可能想要传递日期,但是您将从 某个地方获得它-并且注入一个时钟意味着您可以测试 所有代码。

试试看

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

LINQtoEntities 不支持 Date 属性——如果您尝试在 LINQtoEntities 查询中的 DateTime 字段上使用它,将得到一个错误。但是,您可以使用 Dbfunction 修剪日期。TruncateTime 方法。

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

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

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

我不明白为什么乔恩的方法不起作用。

DateTime dt=DateTime.Now.date;


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

试试这个代码

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

LINQ 碰巧不喜欢 DateTime.Date这样的属性。它只是不能转换为 SQL 查询。所以我想出了一个用乔恩的答案来比较日期的方法,但是没有那个淘气的 DateTime.Date。就像这样:

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

这样,我们就可以比较一个完整的数据库 DateTime,包含所有的日期和时间的东西,比如2015.03-0411:49:45.000或者类似的东西,还有一个 DateTime,代表那天实际的第一毫秒,比如2015.03-0400.00.00.0000。

任何日期时间,我们比较该 DateTime.Today将返回我们安全,如果该日期是较晚或相同。除非你想在同一天进行比较,这样的话,我认为你应该选择凯撒的答案。

DateTime.CompareTo()方法只是一些奇特的面向对象的东西。如果参数早于所引用的 DateTime,则返回 -1; 如果参数是 LITERLY EQUAL (包含所有的 timey 内容) ,则返回0; 如果参数晚于 DateTime,则返回1。

我发现这个问题的时候,我还在纠结于同一个查询。 试试这个:

Var q = db.游戏。其中(t = > t.StartDate。Day = = DateTime 日期时间。现在。开始日期。月份 = = 日期时间。现在。月份及开始日期。年 = = 日期时间。现在。年)。OrderBy (d = > d.StartDate) ;

这样,通过将日期部分分开,我们实际上只比较日期,从而省略了时间。

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

由于您得到了前面提到的错误,因此 .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不为我工作,不幸的故障之间的键盘和椅子,但同时我发现这个替代品。