LINQ to Entities Exception不支持指定的类型成员'Date'

时间:2012-07-22 02:24:37

标签: entity-framework linq-to-entities

我在实现以下语句时遇到异常。

 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.

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

11 个答案:

答案 0 :(得分:214)

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

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


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

答案 1 :(得分:98)

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

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

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

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

答案 2 :(得分:34)

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

答案 3 :(得分:8)

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

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

答案 4 :(得分:3)

尝试使用

return jobdescriptions.AsEnumerable()
.Where(j => j.JobDeadline.Date == Convert.ToDateTime(rule.data).Date );

AsEnumerable()将查询的上下文从LINQ切换到实体到LINQ到对象,因此条件不会转换为SQL

答案 5 :(得分:2)

需要包含using System.Data.Entity;。即使在ProjectTo<>

下也可以正常工作
var ruleDate = rule.data.Date;
return jobdescriptions.Where(j => DbFunctions.TruncateTime(j.Deadline) == ruleDate);

答案 6 :(得分:1)

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

答案 7 :(得分:1)

这对我有用。

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

来源:Asp.net Forums

答案 8 :(得分: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);

答案 9 :(得分:0)

您可以像这样获得枚举:

DateTime todayDate = DateTime.Now.Date; var check = db.tableName.AsEnumerable().Select(x => new
        {
            Date = x.TodayDate.Date
        }).Where(x => x.Date == todayDate).FirstOrDefault();

答案 10 :(得分:0)

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

最简单的选择是使用EF Core。它可以做到这一点。如果不能,则截断的更好替代方法是根本不更改查询的字段,而修改边界。如果您要进行普通的“介于”类型查询,其中上下限是可选的,则可以使用以下技巧。

    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修剪回日期部分,而是增加了查询上限和用户<而不是<=