Entity framework 指定的类型成员';日期';LINQ to Entities异常中不支持

Entity framework 指定的类型成员';日期';LINQ to Entities异常中不支持,entity-framework,linq-to-entities,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.

我在实现以下语句时遇到了一个异常

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

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

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

LINQ to Entities无法将大多数.NET日期方法(包括您使用的转换)转换为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);
可以使用的方法将
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);

更新:
EntityFunctions
在EF6中不推荐使用,请使用
DbFunctions.TruncateTime
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 );
DateTime ruleDate=Convert.ToDateTime(rule.data);
DateTime startDate=SearchDate.Date;
DateTime endDate=SearchDate.Date.AddDay(1);
返回作业描述。其中(j.Deadline>=开始日期
&&j.截止日期<截止日期);

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

对于EF6,使用DbFunctions.TruncateTime(mydate)代替。

它对我有效。

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

(p=>p.UserID==User&&p.ValidityExpiry我也有同样的问题,但我使用日期时间范围。 我的解决方案是将开始时间(包括任何日期)调整为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);
var from=this.setStartTime(yourDateTime);
var to=this.setEndTime(yourDateTime);

yourFilter=yourFilter.And(f=>f.YourDateTime.Value>=from&&f.YourDateTime.Value f.YourDateTime.Value>=from&&f.YourDateTime.Value需要使用System.Data.Entity;
包含
。即使使用
ProjectTo


正如许多人在这里指出的,使用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;
    }
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);
返回x=>x.PoDate!=null&&x.PoDate.Value>=dtMinDate&&x.PoDate.Value

基本上,我们并没有将PoDate调整回日期部分,而是增加查询上限和user<,而不是j=>
j.jobDudate.Date
?Date是JobDudate上的属性吗?这本身不应该导致错误-可能是命名冲突(但不确定这一点)。如果该行仍然导致错误,只需将其重命名为DeadlineDate或类似名称。Date是JobDeadline上的属性。JobDeadline是我要提取日期的DateTime类型。然后,要在LINQ中执行此操作,您只需比较JobDeadline属性,例如j.JobDeadline>ruleDate。这需要进行一些测试,但可以使其正常工作。可选比较.Month.Day和.Year的三个属性(j.Deadline.Year==ruleDate.Year和&j.Deadline.Month==ruleDate.Month和&j.Deadline.Day==ruleDate.Day)。不优雅但有效,因为这些只是整数。嗯。这个想法有效。肮脏但有效。如果你把它作为答案写,我可以将它标记为正确。我注意到,
ruleData
DateTime
类型,并且
j.jobDudate
截断了时间。感觉不对。没有得到异常,但也没有得到预期的结果。@aneal:它会返回所有记录,其中
作业截止日期
规则的日期相同。数据
,无论一天中的时间是什么。这不是你想通过问题中的查询实现的吗?为什么感觉不对?+1和我同意上面的说法,对于99%的实现来说绝对是一个更好的答案在EF6中不推荐使用ons
,您现在应该使用
DbFunctions
。EF6中DbFunctions的名称空间是
System.Data.Entity
:+1作为此答案。
EntityFunctions.TruncateTime
(后来被
DbFunctions.TruncateTime>取代)通过转换为SQL实现,其中datetime转换为字符串并被截断。这会使查询运行速度大大降低,与处理的记录数成比例。正如已经回答的那样,这在EF6和更低版本中都存在。EF core支持
。Date
var from = this.setStartTime(yourStartDateTime);
var to = this.setEndTime(yourEndDateTime);

yourFilter = yourFilter.And(f => f.YourDateTime.Value >= from && f.YourDateTime.Value <= to);
var ruleDate = rule.data.Date;
return jobdescriptions.Where(j => DbFunctions.TruncateTime(j.Deadline) == ruleDate);
    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;
    }