111

我在执行以下语句时遇到了异常。

 DateTime result;
 if (!DateTime.TryParse(rule.data, out result))
     return jobdescriptions;
 if (result < new DateTime(1754, 1, 1)) // sql can't handle dates before 1-1-1753
     return jobdescriptions;
 return jobdescriptions.Where(j => j.JobDeadline.Date == Convert.ToDateTime(rule.data).Date );

例外

The specified type member 'Date' is not supported in LINQ to Entities. Only initializers, entity members, and entity navigation properties are supported.

我知道异常意味着什么,但我不知道如何摆脱它。有什么帮助吗?

4

9 回答 9

240

您可以使用EntityFunctions的TruncateTime方法将属性正确转换为 SQL:Date

using System.Data.Objects; // you need this namespace for EntityFunctions

// ...

DateTime ruleData = Convert.ToDateTime(rule.data).Date;
return jobdescriptions
    .Where(j => EntityFunctions.TruncateTime(j.JobDeadline) == ruleData);


更新: EntityFunctions在 EF6 中已弃用,使用DbFunctions.TruncateTime

于 2012-07-22T13:40:36.227 回答
105

LINQ to Entities 无法将大多数 .NET Date 方法(包括您使用的转换)转换为 SQL,因为没有等效的 SQL。

解决方案是在 LINQ 语句之外使用 Date 方法,然后传入一个值。看起来好像是 Convert.ToDateTime(rule.data).Date 导致了错误。

在 DateTime 属性上调用 Date 也无法转换为 SQL,因此解决方法是比较可以转换为 LINQ 的 .Year .Month 和 .Day 属性,因为它们只是整数。

var ruleDate = Convert.ToDateTime(rule.data).Date;
return jobdescriptions.Where(j => j.Deadline.Year == ruleDate.Year 
                       && j.Deadline.Month == ruleDate.Month 
                       && j.Deadline.Day == ruleDate.Day);
于 2012-07-22T03:22:50.523 回答
39

对于 EF6,请改用 DbFunctions.TruncateTime(mydate)。

于 2013-12-09T17:31:05.310 回答
10

ef6 中的“EntityFunctions.TruncateTime”或“DbFunctions.TruncateTime”正在运行,但在大数据中存在一些性能问题。

我认为最好的方法是这样做:

DateTime ruleDate = Convert.ToDateTime(rule.data);

DateTime  startDate = SearchDate.Date;

DateTime  endDate = SearchDate.Date.AddDay(1);

return jobdescriptions.Where(j.Deadline >= startDate 
                       && j.Deadline < endDate );

这比使用日期的一部分要好。因为查询在大数据中运行得更快。

于 2013-10-01T11:42:40.350 回答
3

需要包括using System.Data.Entity;. 即使与ProjectTo<>

var ruleDate = rule.data.Date;
return jobdescriptions.Where(j => DbFunctions.TruncateTime(j.Deadline) == ruleDate);
于 2019-12-04T06:37:20.773 回答
1

这意味着 LINQ to SQL 不知道如何将Date属性转换为 SQL 表达式。这是因为结构的Date属性DateTime在 SQL 中没有类似的。

于 2012-07-22T02:31:05.990 回答
1

它对我有用。

DateTime dt = DateTime.Now.Date;
var ord = db.Orders.Where
      (p => p.UserID == User && p.ValidityExpiry <= dt);

来源:Asp.net 论坛

于 2017-02-05T20:52:57.590 回答
0

我有同样的问题,但我使用 DateTime-Ranges。我的解决方案是将开始时间(任何日期)操作为 00:00:00,将结束时间操作为 23:59:59 所以我不能再将我的 DateTime 转换为 Date,而是保持 DateTime。

如果您只有一个 DateTime,您还可以将开始时间(任何日期)设置为 00:00:00,将结束时间设置为 23:59:59,然后将其作为时间跨度进行搜索。

var from = this.setStartTime(yourDateTime);
var to = this.setEndTime(yourDateTime);

yourFilter = yourFilter.And(f => f.YourDateTime.Value >= from && f.YourDateTime.Value <= to);

您也可以使用 DateTime-Range:

var from = this.setStartTime(yourStartDateTime);
var to = this.setEndTime(yourEndDateTime);

yourFilter = yourFilter.And(f => f.YourDateTime.Value >= from && f.YourDateTime.Value <= to);
于 2017-02-08T09:17:11.223 回答
0

正如许多人在这里指出的那样,使用 TruncateTime 函数很慢。

如果可以的话,最简单的选择是使用 EF Core。它可以做到这一点。如果你不能,那么一个更好的 truncate 替代方法是根本不更改查询的字段,而是修改边界。如果您正在执行一个正常的“介于”类型查询,其中下限和上限是可选的,那么下面的方法可以解决问题。

    public Expression<Func<PurchaseOrder, bool>> GetDateFilter(DateTime? StartDate, DateTime? EndDate)
    {
        var dtMinDate = (StartDate ?? SqlDateTime.MinValue.Value).Date;
        var dtMaxDate = (EndDate == null || EndDate.Value == SqlDateTime.MaxValue.Value) ? SqlDateTime.MaxValue.Value : EndDate.Value.Date.AddDays(1);
        return x => x.PoDate != null && x.PoDate.Value >= dtMinDate && x.PoDate.Value < dtMaxDate;
    }

基本上,我们不是将 PoDate 修剪回 Date 部分,而是增加查询上限和用户 < 而不是 <=

于 2020-05-19T06:02:49.900 回答