Linq to EntityFramework DateTime

Yuc*_*cel 103 c# linq datetime entity-framework

在我的应用程序中,我使用的是实体框架.

我的表

-Article
-period
-startDate
Run Code Online (Sandbox Code Playgroud)

我需要匹配=>的记录 DateTime.Now > startDate and (startDate + period) > DateTime.Now

我试过这个代码,但现在正在运行

Context.Article
    .Where(p => p.StartDate < DateTime.Now)
    .Where(p => p.StartDate.AddDays(p.Period) > DateTime.Now)
Run Code Online (Sandbox Code Playgroud)

当我运行我的代码时,会发生以下异常

LINQ to Entities无法识别方法'System.DateTime AddDays(Double)'方法,并且此方法无法转换为商店表达式.

Jus*_*ner 192

使用LINQ to Entity Framework时,Where子句中的谓词将转换为SQL.你得到了这个错误,因为没有SQL的翻译DateTime.Add()是有道理的.

一个快速的解决方法是将第一个Where语句的结果读入内存,然后使用LINQ to Objects完成过滤:

Context.Article.Where(p => p.StartDate < DateTime.Now)
               .ToList()
               .Where(p => p.StartDate.AddDays(p.Period) > DateTime.Now);
Run Code Online (Sandbox Code Playgroud)

如果您使用的是.NET 4.0,还可以尝试使用EntityFunctions.AddDays方法:

Context.Article.Where(p => p.StartDate < DateTime.Now)
               .Where(p => EntityFunctions.AddDays(p.StartDate, p.Period)
                   > DateTime.Now);
Run Code Online (Sandbox Code Playgroud)

注意:EF 6现在就是System.Data.Entity.DbFunctions.AddDays.

  • 这是一个危险的解决方法,如果ToList()返回大量数据会发生什么? (39认同)
  • 感谢EntityFunctions.AddDays提示我使用EF .net 4.0,但我不知道EntityFunctions,将调查它. (7认同)
  • @SaeedAlg - 在第一个例子中,有必要将项目读入内存.在第二个例子中,我保留了两个Where子句以匹配原始格式.即使您将两者压缩为单个Where子句,Entity Framework也会生成身份SQL,因此这实际上是一个可读性问题. (2认同)
  • @Justin Niessner非常感谢,我想这样做四个小时,你再次感谢我的生命 (2认同)
  • 在给EF"快速"解决方法时,我们都应该避免使用ToList和ToArray方法.它可以快速计算之前的日期并与该值进行比较,并且可以在EF查询中使用,而无需在内存中实例化其结果. (2认同)

and*_*rew 87

我认为这是最后一个答案试图建议的,而不是试图为p.startdat添加天数(不能转换为sql语句的东西)为什么不做一些可以等同于sql的东西:

var baselineDate = DateTime.Now.AddHours(-24);

something.Where(p => p.startdate >= baselineDate)
Run Code Online (Sandbox Code Playgroud)

  • 这是一个比获得更多选票的公认答案更好的答案.它更简单,更安全,更高效. (9认同)
  • @Adrian Carr-对于这种用例可能更好,但不如“ EntityFunctions”解决方案那么多。在此,第二个操作数不从查询中的另一个实体中检索,而是可以在查询之前进行计算。如果要在db中找到两个操作数,则“ EntityFunctions”解决方案仍然适用,而此响应的解决方案将不再起作用。 (2认同)