【发布时间】:2019-10-25 08:04:03
【问题描述】:
在实现规范模式时,我想出了这段代码
public static class ItemSpecification
{
static public Expression<Func<Item, bool>> TodayOnlySpecification { get; } = item => item.ImplementationDate == DateTime.Today;
}
此表达式稍后将在 EF linq 过滤器中用于构建查询。我的问题是,查询中实际使用了什么日期。是静态类首次初始化的日期吗?或者TodayOnlySpecification被引用的日期?
一个具体的场景是
我的应用程序今天启动,我第一次引用
TodayOnlySpecification进行 linq 查询,它应该使用今天的日期作为最终的 sql我的应用程序一直在运行,我明天再次引用
TodayOnlySpecification进行另一个 linq 查询,查询中是使用今天的日期还是使用明天的日期?
编辑 1:
使用DateTime.Now 和DateTime.Today 进行测试会产生截然不同的结果
-
DateTime.Now产生以下 SQL 查询:select ... from ... where [Extent1].[ImplementationDate] = (SysDateTime()) -
DateTime.Today产生以下 SQL 查询:select ... from ... where [Extent1].[ImplementationDate] = @p__linq__0',N'@p__linq__0 datetime2(7)',@p__linq__0='2019-06-11 00:00:00'`
这只是一个猜测,linq to entity 能够将DateTime.Now 转换为SysDateTime() 的事实意味着它没有使用DateTime.Now 的值进行转换。相反,它是在生成 SQL 时使用获取当前时间的方法。这也应该意味着DateTime.Today 被捕获为方法而不是值。
编辑 2:
这就带来了另一个问题,如果 EF 有时在客户端评估方法(例如DateTime.Today),有时在服务器端评估(例如DateTime.Now),这可能有不同的时区,怎么能确定 EF 查询的确切行为?
【问题讨论】:
-
我建议使用
DateTime.Now并自己测试它。如果/何时更改值,您会很快看到。 -
没错。当您对其进行测试时(您在发布问题之前确实对其进行了测试,不是吗?),发生了什么?这是你想要发生的事情吗?你预期会发生什么?为什么或为什么不?
-
请注意,通常 lambda 表达式将捕获变量,而不是值。但是,使用 EF 可能会使事情变得复杂,这取决于表达式的计算时间。这实际上更像是一个 EF 问题,而不是 LINQ、lambda 或闭包问题(即您的问题被严重错误标记)。
-
@mjwills 好主意。应该使用 DateTime.Now 进行测试。我太担心用 DateTime 测试两天了。今天
-
你也可以通过使用 DateTime.Now 分析你的数据库来测试这个
标签: c# entity-framework linq lambda closures