实体框架查询中的Datetime.UtcNow评估与C#IL中的DateTime.UtcNow不同

时间:2016-01-08 19:56:41

标签: c# entity-framework linq datetime azure

在SQL Server评估的EF查询中是否有DateTime函数,因为运行IL的机器会评估查询表达式之外的DateTime函数?

我有一个具有SalesOrders的应用程序

public class SalesOrder
{
   public Int32 OrderID {get;set;}
   public DateTime Expiration {get;set;} 
}

我执行EF查询并在执行此操作时得到不同的结果:

DateTime utcnow = DateTime.UtcNow;

var open = (from a in context.SalesOrders
            where a.Expiration > utcnow
            select a).ToList();

比我这样做时:

var open = (from a in context.SalesOrders
            where a.Expiration > DateTime.UtcNow
            select a).ToList();

我认为这是因为实体框架查询中的DateTime.UtcNow是由SQL Server评估的,与查询之外的DateTime.UtcNow相比,是由运行IL的机器评估的; I'm basing that off this answer

我在Azure平台中作为服务,如果重要的话,使用Azure SQL DB在本地进行调试。

3 个答案:

答案 0 :(得分:6)

你的想法是正确的。

在SQL Server上,您的第一个查询运行以下SQL查询:

exec sp_executesql N'SELECT 
    [Extent1].[OrderID] AS [OrderID], 
    [Extent1].[Expiration] AS [Expiration]
    FROM [dbo].[SalesOrders] AS [Extent1]
    WHERE [Extent1].[Expiration] > @p__linq__0',N'@p__linq__0 datetime2(7)',@p__linq__0='2016-01-08 20:05:25.4433282'

这里很清楚客户的时间是作为参数传递的。

您的第二个查询将其发送到SQL服务器:

SELECT 
    [Extent1].[OrderID] AS [OrderID], 
    [Extent1].[Expiration] AS [Expiration]
    FROM [dbo].[SalesOrders] AS [Extent1]
    WHERE [Extent1].[Expiration] > (SysUtcDateTime())

很明显,使用了SQL Server时钟。

答案 1 :(得分:2)

DateTime.UtcNow映射到CurrentUtcDateTime()。以下是完整列表:

CLR Method to Canonical Function Mapping

答案 2 :(得分:-1)

没有。当您编写一个比较日期的查询时,EF会创建一个Datetime参数,将其发送到SQL Server,然后由服务器完成比较。