在一定一天结束时获得日期时间



我有以下

 DateTime today = DateTime.Today; // or DateTime.UtcNow.Date;

现在,我不能在Linq-EF中做类似的事情,因为Date不能翻译成SQL:

 context.Records.Where(r => r.CreationDate.Date == today);

所以,我总是做这样的事情:

 DateTime dayEnd = today.AddDays(1).AddMilliseconds(-1);
 context.Records.Where(r => r.CreationDate >= today && r.CreationDate <= dayEnd);

现在,有没有更好的方法来获得时间结束DateTime,而不是添加一天然后服用一毫秒?

而不是使用EntityFunctions.TruncateTime

context.Records.Where(r => EntityFunctions.TruncateTime(r.CreationDate) == today);

您也可以通过将条件更改为<来跳过AddSeconds(-1)

DateTime tomorrow = today.AddDays(1);
context.Records.Where(r => r.CreationDate >= today && r.CreationDate < tomorrow);

之类的问题
DateTime today = DateTime.Today ;
Context.Records.Where(r => EntityFunctions.TruncateTime(r.CreationDate) == today) ;

基础SQL可能会看起来像这样:

select *
from some_table r
where convert(date,r.CreationDate) == @today

由于该列现在是表达式的一部分,因此SQL引擎无法使用其可用的任何覆盖索引。除非您有其他使用索引的标准,否则您将进行表扫描。借助大桌子,这将导致性能问题。

您应该避免明显的

DateTime today  = DateTime.Today ;
DateTime dayEnd = today.AddDays(1).AddMilliseconds(-1);
context.Records.Where(r => r.CreationDate >= today && r.CreationDate <= dayEnd) ;

由于SQL Server datetime值的工作方式:虽然它们以毫秒为单位计数,因此SQL Server的" ticks"以3和4毫秒的增量出现。有关详细信息,请参阅我对SQLDATETIME如何进行精确降低的答案。但简而言之:

以SQL Server执行的方式进行转换,请执行以下操作: 以实际考虑的时间为毫秒的一部分,该价值为0-999, Modulo 100.这为您提供了低订单数字,值为0-9。因此,如果当前时间 IS是23:57:23.559,毫秒组件为559。Modulo100您得到9。

  1. 值0和1被"舍入"到0。
  2. 值2、3和4被"舍入"到3。
  3. 值5、6、7和8被"舍入"到7。
  4. 一个值为9的值是圆形的向上到0 效果:如果时间的毫秒部分为999,则滴答1毫秒。这 意味着时间23:59:59.999被四舍五入到第二天。所以'31的转换 2010年12月23日:59:59.99'产生的日期时间值为... 2011年1月1日00:00:00.000。

请注意,smalldatetime也表现出这种行为。仅datetime2是豁免的。

SO ...

除非您小心,否则将事情放在时间浪费的地板上真的很容易(不要问我怎么知道)。

您最好做

之类的事情
DateTime today    = DateTime.Today ;
DateTime tomorrow = today.AddDays(1);
context.Records.Where(r => r.CreationDate >= today && r.CreationDate < tomorrow) ;

应该转化为看起来像

的SQL
select *
from some_table r
where r.CreationDate >= @today
  and r.CreationDate <  @tomorrow

并将允许优化器在日期/时间列中使用索引。

您可以使用entityfunctions.truncatetime:

context.Records.Where(r => EntityFunctions.TruncateTime(r.CreationDate) == today);

使用sqlfunctions作为" dayofyear"one_answers" Year":

context.Records.Where(r => 
SqlFunctions.DatePart("dayofyear", r.CreationDate) == DateTime.Now.DayOfYear 
&& SqlFunctions.DatePart("year", r.CreationDate) == DateTime.Now.Year);

最新更新