3

我目前在使用 LINQ->Entites w/Entity Framework v 4.2 和 T4 生成的对象上下文时遇到问题。我相对了解在对数据库执行之前如何将 LINQ 查询转换为存储表达式,但我绝不是专家。据我了解,使用的 .NET 函数将转换为 T-SQL 中的等效函数,而那些没有等效函数(例如)的函数将在运行时String.Format()抛出 a 。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 方法。非常感谢任何帮助/反馈!

4

4 回答 4

13

LINQ 表达式转换为底层数据源语言,在您的情况下SQL,它和 LINQ to EntitiesDateTime.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);

但是在您的情况下,如果您可以事先计算值,就像在您的第二个代码示例中一样,那么它会更好,因为这将避免每条记录的转换。

于 2013-10-11T17:47:22.810 回答
5

EntityFunctions 已过时 (EF 6.x)。

请使用DbFunctions类进行 DateTime 操作。

例如从 cmd in context.Commands where cmd.ExecutedOn > DbFunctions.AddMilliseconds(baseDate, millisecondsToAdd) 选择 cmd

于 2014-06-20T11:21:14.693 回答
1

我已经使用了DbFunction很长时间,直到今天我才意识到……为什么我什至需要为此烦恼DbFunction

这就是我想到的:

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

我只是'AddMinutes'从 linq 表达式中取出操作。

于 2021-05-25T10:53:03.407 回答
0

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

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

于 2013-10-11T17:47:43.893 回答