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

时间:2013-10-11 17:44:32

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

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

在我的动态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-&gt;实体将DateTime.Now.AddMinutes()视为没有T-SQL等效的.NET方法。非常感谢任何帮助/反馈!

4 个答案:

答案 0 :(得分:10)

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);

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

答案 1 :(得分:4)

EntityFunctions已过时(EF 6.x)。

请使用DbFunctions类进行DateTime操作。

例如来自cmd in context.Commands其中cmd.ExecutedOn&gt; DbFunctions.AddMilliseconds(baseDate,millisecondsToAdd)选择cmd

答案 2 :(得分:1)

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

这是我想到的:

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

我刚刚从 linq 表达式中去掉了 'AddMinutes' 操作。

答案 3 :(得分:0)

  

我真的很想理解为什么LINQ-&gt;实体将DateTime.Now.AddMinutes()视为没有T-SQL等价的.NET方法

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