我有以下
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
而不是增加一天然后花费一毫秒?
答案 0 :(得分:5)
改为使用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);
答案 1 :(得分:1)
您可以使用EntityFunctions.TruncateTime:
context.Records.Where(r => EntityFunctions.TruncateTime(r.CreationDate) == today);
答案 2 :(得分:1)
将SqlFunction用于“dayofyear”和“year”:
context.Records.Where(r =>
SqlFunctions.DatePart("dayofyear", r.CreationDate) == DateTime.Now.DayOfYear
&& SqlFunctions.DatePart("year", r.CreationDate) == DateTime.Now.Year);
答案 3 :(得分:1)
像
这样的问题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的“滴答”以3毫秒和4毫秒的增量发生。有关详细信息,请参阅问题my answer的How does SqlDateTime do its precision reduction。但简而言之:
要以SQL Server的方式进行转换,请执行以下操作: 取考虑的实际时间的毫秒部分,值为0-999, 模数100.它为您提供低位数字,从0到9的值。所以如果是当前时间 是23:57:23.559,毫秒组件是559.模数100你得到9。
- 值0和1“向下舍入”为0.
- 值2,3和4是“向下舍入”至“3”。
- 值5,6,7和8“向下舍入”为7。
- 值为9将 UP 舍入为0.这有一个相当不愉快和讨厌的一面 效果:如果时间的毫秒部分是999,则它会上升1毫秒。这个 表示时间23:59:59.999向上舍入为下一天。所以'31的转换 2010年12月23日:59:59.999'的日期时间值为... 2011年1月1日00:00:00.000。
醇>
请注意,smalldatetime
也表现出这种行为。只有datetime2
可以免除。
<强>因此... 强>
除非你小心谨慎,否则很容易将掉落在地板上的东西放在正确的时间戳上(不要问我怎么知道)。
你最好做一些像
这样的事情DateTime today = DateTime.Today ;
DateTime tomorrow = today.AddDays(1);
context.Records.Where(r => r.CreationDate >= today && r.CreationDate < tomorrow) ;
应该转换为类似
的SQLselect *
from some_table r
where r.CreationDate >= @today
and r.CreationDate < @tomorrow
并允许优化器使用日期/时间列上的索引。