c# - 动态 LINQ 查询中 DateTime.AddMinutes() 的问题

标签 c# sql linq datetime entity-framework-4

我目前在使用 LINQ->Entites w/Entity Framework v 4.2 和 T4 生成的对象上下文时遇到问题。我比较了解 LINQ 查询在针对数据库执行之前如何转换为存储表达式,但我绝不是专家。据我了解,所使用的 .NET 函数被转换为它们在 T-SQL 中的等效函数,而那些没有等效函数的函数(例如 String.Format())将抛出一个 System.NotSupportedException 在运行时。

在我的动态 LINQ 查询中,我使用 DateTime.Now.AddMinutes() 来过滤我的结果集:

public void ExecuteSearch()
{
   var timeElapsedTresholdInMinutes = Convert.ToInt32( ConfigurationManager.AppSettings.Get("TimeElapsedThresholdInMinutes") );

   var resultSet = ( from entity in _dbContext.EntityCollection
                     where /*non-date-related where clause stuff*/
                           && 
                           entity.DateAdded <= DateTime.Now.AddMinutes(-1 * timeElapsedThresholdInMinutes)
                     select entity);

   /* do something with resultSet */
}

在运行时,我收到 System.NotSupportedException:LINQ to Entities 无法识别方法 DateTime.Now.AddMinutes() 方法并且此方法无法转换为存储表达式。

例如,我的 timeElapsedThreshold 在评估后的值为 -30。有谁知道为什么这不会映射到 DATEADD(MINUTE,-30,GETDATE());?我在这里遗漏了什么吗?

当然,我可以将我的代码变成:

public void ExecuteSearch()
{
   var maxDateTimeThreshold = DateTime.Now.AddMinutes( -1 * Convert.ToInt32(ConfigurationManager.AppSettings.Get("TimeElapsedThresholdInMinutes"));

   var resultSet = ( from entity in _dbContext.EntityCollection
                     where /*non-date-related where clause stuff*/
                           && 
                           entity.DateAdded <= maxDateTimeThreshold
                     select entity);
}

并克服了我的代码中断问题,但我真的很想了解为什么 LINQ->Entities 将 DateTime.Now.AddMinutes() 视为没有 T- 的 .NET 方法SQL等效。非常感谢任何帮助/反馈!

最佳答案

LINQ Expression 转换为底层数据源语言,在您的情况下为 SQL,而在 LINQ to Entities DateTime.AddMinutes 中没有任何可转换的实现对 SQL 中相应等效项的查询。这就是提供 .Net 框架的原因。

System.Data.Objects.EntityFunctions.AddMinutes

您应该看到:Date and Time Canonical Functions

您可以将查询作为:

   var resultSet = ( from entity in _dbContext.EntityCollection
                     where /*non-date-related where clause stuff*/
                           && 
                           entity.DateAdded <= 
                          System.Data.Objects.EntityFunctions.AddMinutes(
                                 DateTime.Now, -1 * timeElapsedThresholdInMinutes)
                     select entity);

但在您的情况下,如果您可以像在第二个代码示例中那样预先计算值,那会更好,因为这样可以避免对每条记录进行转换。

关于c# - 动态 LINQ 查询中 DateTime.AddMinutes() 的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19324234/

相关文章:

c# - Web 应用程序中 Entity Framework 核心可能的内存泄漏

sql - 从表到表批量插入

c# - 使用 Linq 有条件地更改数据表列的值

c# - 使用 Linq-to-XML 和 Linq-to-SQL 生成非常大的 XML 文件

c# - 记录在 WCF REST 中收到的每条消息

c# - 如何将嵌套的 Document 反序列化为特定的类对象?

c# - 我是否应该将 async/await 添加到单行函数中?

php - 将原始 SQL 查询更改为 Laravel 查询生成器对象

mysql - 使用 select * 和 select askid 得到不同的结果

c# - Entity Framework AsNoTracking 中断对 Distinct 的调用