【问题标题】:What will be captured by the C# Entity Framework linq queryC# Entity Framework linq 查询将捕获什么
【发布时间】: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被引用的日期?

一个具体的场景是

  1. 我的应用程序今天启动,我第一次引用 TodayOnlySpecification 进行 linq 查询,它应该使用今天的日期作为最终的 sql

  2. 我的应用程序一直在运行,我明天再次引用 TodayOnlySpecification 进行另一个 linq 查询,查询中是使用今天的日期还是使用明天的日期?

编辑 1:

使用DateTime.NowDateTime.Today 进行测试会产生截然不同的结果

  1. DateTime.Now 产生以下 SQL 查询:

    select ... 
    from ...
    where [Extent1].[ImplementationDate] = (SysDateTime())
    
  2. 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


【解决方案1】:

捕获的是

Expression.Call(
    null, //Static call so no instance
    methodOf(DateTime.Now),
    new Type[0] //No generic arguments
);

换句话说。什么都没有被捕获。

我建议您使用调试器检查 IQueryable&lt;T&gt;.Expression 以查看树。

编辑:

回答您关于 EntityFramework 如何处理上述表达式的问题。它没有。由EntityFramework Provider的实现来处理。

在 EntityFramework.SqlServer 的情况下,处理此问题的代码位于此处

SqlFunctionCallHandler.HandleCanonicalFunctionCurrentDateTime 1259 行

【讨论】:

    猜你喜欢
    • 2021-07-12
    • 1970-01-01
    • 1970-01-01
    • 2023-03-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-19
    • 1970-01-01
    相关资源
    最近更新 更多