LINQ to Entities 异常中不支持指定的类型成员“日期”
Posted
技术标签:
【中文标题】LINQ to Entities 异常中不支持指定的类型成员“日期”【英文标题】:The specified type member 'Date' is not supported in LINQ to Entities Exception 【发布时间】:2012-07-20 19:03:30 【问题描述】:我在执行以下语句时遇到了异常。
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.
我知道异常意味着什么,但我不知道如何摆脱它。有什么帮助吗?
【问题讨论】:
这是在 EF6 及更低版本中。 EF 核心支持.Date
。
【参考方案1】:
您可以使用EntityFunctions 的TruncateTime 方法将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
【讨论】:
好吧,我注意到ruleData
是DateTime
类型,而j.JobDeadline
有截断时间。感觉不对。没有得到异常,但也没有得到预期的结果。
@aneal:它返回所有JobDeadline
与rule.data
具有相同日期 的记录,无论一天中的什么时间 .这不是您想通过问题中的查询实现的目标吗?为什么感觉不对?
+1 我同意上述观点,这对于 99% 的实现来说绝对是一个更好的答案
请注意,EntityFunctions
在 EF6 中已弃用,您现在应该使用 DbFunctions
。
EF6 中 DbFunctions 的命名空间是 System.Data.Entity
: msdn.microsoft.com/en-us/library/Dn220142(v=VS.113).aspx【参考方案2】:
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);
【讨论】:
j =>j.JobDeadline.Date
呢?
Date 是 JobDeadline 上的属性吗?这本身不应该导致错误 - 可能是命名冲突(但不确定)。如果该行仍然导致错误,只需将其重命名为 DeadlineDate 或类似名称。
日期是 JobDeadline 的财产。 JobDeadline 是我要提取日期的 DateTime 类型。
然后,要在 LINQ 中工作,您只需比较 JobDeadline 属性,例如 j.JobDeadline > ruleDate。这需要一些测试,但可以使其工作。或者比较 .Month .Day 和 .Year 的三个属性(j.Deadline.Year == ruleDate.Year && j j.Deadline.Month == ruleDate.Month && j.Deadline.Day == ruleDate.Day)。不优雅,但它可以工作,因为这些只是整数。
嗯。这个想法有效。脏但有效。如果您将其写为答案,我可以将其标记为正确。【参考方案3】:
对于 EF6,请改用 DbFunctions.TruncateTime(mydate)。
【讨论】:
【参考方案4】: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 );
这比使用部分日期要好。因为查询在大数据中运行得更快。
【讨论】:
这个答案+1。EntityFunctions.TruncateTime
(后来被 DbFunctions.TruncateTime
取代)通过转换为 SQL 来实现,其中日期时间被转换为字符串并被截断。这使得查询运行速度明显变慢,与处理的记录数成正比。【参考方案5】:
需要包含using System.Data.Entity;
。即使使用 ProjectTo<>
也能正常工作
var ruleDate = rule.data.Date;
return jobdescriptions.Where(j => DbFunctions.TruncateTime(j.Deadline) == ruleDate);
【讨论】:
已经回答here【参考方案6】:这意味着 LINQ to SQL 不知道如何将Date
属性转换为 SQL 表达式。这是因为DateTime
结构的Date
属性在SQL 中没有类似物。
【讨论】:
【参考方案7】:它对我有用。
DateTime dt = DateTime.Now.Date;
var ord = db.Orders.Where
(p => p.UserID == User && p.ValidityExpiry <= dt);
来源:Asp.net Forums
【讨论】:
【参考方案8】:我有同样的问题,但我使用的是 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】:正如许多人在这里指出的那样,使用 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 部分,而是增加查询上限和用户
【讨论】:
以上是关于LINQ to Entities 异常中不支持指定的类型成员“日期”的主要内容,如果未能解决你的问题,请参考以下文章
在LINQ to Entities中不支持指定的类型成员'x'。只支持初始化器实体成员和实体导航属性。
LINQ to Entities 不支持指定的类型成员“日期”。 DbFunctions.TruncateTime()
无法将类型“System.Nullable`1”强制转换为类型“System.Object”。LINQ to Entities 仅支持强制转换 EDM 基元或枚举类型。