LINQ to Entity 减去 2 个日期

Posted

技术标签:

【中文标题】LINQ to Entity 减去 2 个日期【英文标题】:LINQ to Entities for subtracting 2 dates 【发布时间】:2010-10-08 22:09:44 【问题描述】:

我正在尝试使用带有实体框架的 LINQ 来确定两个日期之间的天数。它告诉我它无法识别 System.TimeSpan 类上的 Subtract

这是我的 LINQ 查询的 where 部分。

where ((DateTime.Now.Subtract(vid.CreatedDate).TotalDays < maxAgeInDays))

这是我在 VS.NET 调试器中收到的错误

"LINQ to Entities 无法识别方法 'System.TimeSpan Subtract(System.DateTime)' 方法,并且该方法无法转换为存储表达式。"

我做错了什么还是有更好的方法来获取实体框架中 2 个 DateTimes 之间的天数?

谢谢 迈克尔

【问题讨论】:

我还尝试通过将公式更改为以下公式来避免时间跨度 - 这仍然不起作用 where (vid.CreatedDate.AddDays(maxAgeInDays) >= DateTime.Now) 【参考方案1】:

在这种情况下,接受的答案更好,但作为参考,您可以使用 EntityFunctions 类对日期执行操作等。

where (vid.CreatedDate >= EntityFunctions.AddDays(DateTime.Now, -maxAgeInDay))

【讨论】:

谢谢,这正是我想要的。 请注意,这仅在 Entity Framework v4 中受支持。这不适用于 Entity Framework v1。 EntityFunctions 已弃用。 DbFunctions 是新的类。 有人用DbFunctions 进行单元测试吗?我没有运气。 正如其他人所指出的,EntityFunctions 已被弃用。这是用于复制/粘贴目的的完整示例:System.Data.Entity.DbFunctions.AddDays(DateTime.Now, -maxAgeInDay)【参考方案2】:

这是我的工作方式

我定义了一个代表最早日期的日期时间变量

DateTime oldestDate = DateTime.Now.Subtract(new TimeSpan(maxAgeInDays, 0, 0, 0, 0));
...

然后我修改了 LINQ 查询的 where 部分

where (vid.CreatedDate >= oldestDate )

工作就像一个魅力 - 感谢 Micah 让我思考表达式树

【讨论】:

您应该已将@Micah 标记为答案,并在他的回复中添加评论或使用最终答案更新您的问题。 聪明,聪明聪明。简单直接。我仍然想知道为什么它没有首先出现在我身上。感谢分享【参考方案3】:

你也可以使用System.Data.Objects.EntityFucntions:

currentDate = DateTime.Now;

...
where  EntityFunctions.DiffDays(currentDate, vid.CreatedDate) < maxAgeIdDays 

EntityFunctions 中的所有函数仅用于 Linq-to-entities,并映射到 SQL 函数。

【讨论】:

@Morten:那是类型,它们仅适用于 Linq-to-entities。 许多 SQL Server 特定功能可通过 System.Data.Objects.SqlClient.SqlFunctions 类获得。当然,数据存储必须是 SQL Server 才能工作。更多信息:msdn.microsoft.com/en-us/library/… 另外值得注意的是,一旦升级到 EF 6+,System.Data.Objects.EntityFucntions 就会过时,而是使用:System.Data.Entity.DbFunctions 此函数已弃用,请改用 DbFunctions.DiffMilliseconds(o.DateReceived, o.DateOrder)【参考方案4】:

您会遇到这类问题,因为谓词需要转换为表达式树。而且翻译过程无法识别 DateTime.Now.Subtract 方法。

【讨论】:

有没有办法做我想做的事情,以便我可以翻译成表达式树?【参考方案5】:

事实上,根据设计,LINQ to Entities 需要将整个查询转换为 SQL 语句。那就是它无法识别 Subtract 方法的地方。每当您尝试在查询中使用 C#/VB 方法时,都会发生这种情况。在这些情况下,您必须想办法从查询中提取该部分。 这篇文章解释了更多: http://mosesofegypt.net/post/LINQ-to-Entities-what-is-not-supported.aspx

【讨论】:

这个答案是正确的,但绝对不是我想要的答案。 LINQ to SQL 支持尽可能多地调用外部方法,因此这种权衡是不幸的。【参考方案6】:

您可以在模型中定义新属性:

    public DateTime StartDate get; set; 
    public DateTime EndDate get; set; 
    public TimeSpan CalculateTime
        get
        
            return EndDate.Subtract(StartDate);
        
    

现在,你可以使用类似的东西:

var query = from temp in db.Table
select new MyModel 
    Id = temp.Id,
    Variable1 = temp.Variable1,
    ...
    EndDate = temp.EndDate,
    StartDate = temp.StartDate

当你查看结果时,你可以使用 return 如:

return query

现在,在查询中,我们有CalculateTime(在EndDate 和Startdate 之间减去)。

【讨论】:

仅当您有权访问模型的源代码时才有效。

以上是关于LINQ to Entity 减去 2 个日期的主要内容,如果未能解决你的问题,请参考以下文章

减去 2 个日期得到天数

oracle sql pl/sql 如何减去日期/工作周

Linq to Entities 日期部分优化

Jquery datepicker setDate减去给定日期的一天

在 Linq-to-Entities 查询中格式化日期会导致异常

Linq to Join 表基于两者之间的日期