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

本文关键字:AddMinutes 问题 DateTime LINQ 查询 动态 | 更新日期: 2023-09-27 18:34:53

我目前在使用带有实体框架 v 4.2 和 T4 生成的对象上下文的 LINQ->Entites 时遇到了问题。 我对 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 does not recognize the method DateTime.Now.AddMinutes() method and this method cannot be translated into a store expression.

例如,我的 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-SQL 等效项的 .NET 方法。 任何帮助/反馈将不胜感激!

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

LINQ

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

System.Data.Objects.EntityFunctions.AddMinutes

您应该看到: 日期和时间规范函数

您可以将查询设置为:

   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);
但在您的情况下,最好是可以

事先计算值,就像在第二个代码示例中一样,因为这将避免每条记录的转换。

EntityFunctions 已过时 (EF 6.x(。

请使用 DbFunctions 类进行日期时间操作。

例如,来自上下文中的 CMD。其中 cmd.ExecutedOn> DbFunctions.AddMilliseconds(baseDate, millisecondsToAdd( 选择 cmd 的命令

我已经使用DbFunction很长时间了,直到今天我才意识到......为什么我什至需要为那个DbFunction而烦恼。

这是我想到的:

var dateLimit = DateTime.Now.AddMinutes(-20);
var result = db.TableName.Where(x => x.MyDateTime > dateLimit);

我只是从 linq 表达式中删除了'AddMinutes'操作。

我真的很想了解为什么 LINQ->Entities 将 DateTime.Now.AddMinutes(( 视为没有 T-SQL 等效项的 .NET 方法。

因为从 .NET 到 T-SQL 的每个映射都必须手动实现,而他们只是没有实现这个......