6

更新:我原来的问题是无效的,因为我误读了 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按值传递一个常规结构吗?

如果我在 LINQ 查询中使用var now = DateTime.Now;然后使用该now变量,则日期将作为文字传递。这是怎么回事?

4

3 回答 3

4

LINQ-to-whatever 通过解析表达式树来将 .NET 代码转换为适当的 SQL 语言来运行。这允许查询尽可能多地在数据库端而不是客户端处理。结果,当你说:

... myField <= DateTime.Now

解析器使用表达式引用DateTime.Now,而不对其进行评估,以便将尽可能多的代码转换为适当的 SQL 语言。这就是 LINQ 高效工作的原因,但作为副作用,查询中的所有内容都被解释为表达式并尝试转换为适当的 SQL 代码。当您将其存储在变量中时,如下所示:

var now = DateTime.Now;

该值被立即评估并存储到now中,并且该值在您的查询中按字面意思使用,而不是表达式。

于 2012-05-21T21:38:41.900 回答
3

DateTime.Now是一个函数(Now 属性的 getter),因此 linq2EF 在尝试创建表达式树时会将其视为函数。这就像说,.ToString()link2EF 中的工作原理。此外,当您从临时变量中使用它时,它将被视为临时变量,就像您将结果保存.ToString()在临时变量中一样,最终更改不会影响您的输出。

于 2012-05-21T21:38:57.870 回答
0

很好的问答。我只是想在使用 Microsoft SQL Server 2008 R2 的环境中添加它,DateTime.Now在 LINQ to Entities 查询中引用会生成以下 SQL 表达式:

CAST( SysDateTime() AS datetime2)

我相信这将类似于NOW()在 MySQL 中生成,因此无论底层数据库如何,都会看到相同的行为。

当然,如果您想要运行 LINQ 代码的本地时间而不是数据库服务器,那么这种行为可能会成为问题。正如预期的那样,分配DateTime.Now给局部变量并在 LINQ 表达式中使用它的解决方法在 MS SQL 中运行良好。

于 2012-08-20T22:27:33.930 回答