更新:我的原始问题无效,因为我误读了MySql日志。抱歉。请参阅下文,更新。
我正在使用LINQ查询:
var homework = ctx.Threads.Where(t => t.ClassName == "10L"
&& t.EndDate != null
&& t.StartDate <= DateTime.Now
&& t.EndDate > DateTime.Now)
.OrderByDescending(o => o.EndDate)
.FirstOrDefault();
这将创建SQL(MySQL 5.5.14):
SELECT
`Project1`.`id`,
`Project1`.`title`,
`Project1`.`startdate`,
`Project1`.`enddate`,
`Project1`.`class`,
`Project1`.`body`,
`Project1`.`threadtype`
FROM (SELECT
`Extent1`.`id`,
`Extent1`.`title`,
`Extent1`.`startdate`,
`Extent1`.`enddate`,
`Extent1`.`class`,
`Extent1`.`body`,
`Extent1`.`threadtype`
FROM
`threads` AS `Extent1`
WHERE (((`Extent1`.`class` = '10L')
AND (`Extent1`.`enddate` IS NOT NULL))
AND (`Extent1`.`startdate` <= (NOW())))
AND (`Extent1`.`enddate` > (NOW())))
AS `Project1`
ORDER BY `Project1`.`enddate` DESC
LIMIT 1
LINQ to EF如何知道使用NOW()
函数?当然,我只是按值传递一个普通的DateTime
结构?
如果我使用var now = DateTime.Now;
然后在LINQ查询中使用now
变量,则日期将作为文字传递。发生了什么事?
答案 0 :(得分:4)
LINQ-to-whatever通过解析表达式树来从.NET代码转换为适当的SQL语言。这允许查询尽可能多地处理数据库端而不是客户端。结果,当你说:
... myField <= DateTime.Now
解析器使用表达式引用DateTime.Now
,而不进行评估,以便尽可能地将代码转换为适当的SQL语言。这是允许LINQ高效工作的原因,但作为副作用,查询中的所有被解释为表达式并尝试转换为适当的SQL代码。当您将其存储在变量中时,如:
var now = DateTime.Now;
立即评估该值并将其存储到now
中,该值将在您的查询中使用,而不是表达式。
答案 1 :(得分:3)
DateTime.Now
是一个函数(Now属性的getter),所以linq2EF在尝试创建表达式树时会将其视为函数。这就像是说.ToString()
在link2EF中是如何工作的。此外,当您从临时变量中使用它时,它将被视为临时变量,就像将.ToString()
的结果保存在临时变量中一样,最终更改不会影响您的输出。
答案 2 :(得分:0)
好问答。我只是想在我的环境中添加它,它使用Microsoft SQL Server 2008 R2,在LINQ to Entities查询中引用DateTime.Now
会生成以下SQL表达式:
CAST( SysDateTime() AS datetime2)
我相信这与在MySQL中生成NOW()
类似,因此无论底层数据库如何,都会看到相同的行为。
当然,如果您希望运行LINQ代码的本地时间而不是数据库服务器,则此行为可能会出现问题。将DateTime.Now
分配给局部变量并在LINQ表达式中使用它的解决方法与MS SQL一样正常,正如预期的那样。