我在实现以下语句时遇到异常。
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.
我知道异常意味着什么,但我不知道如何摆脱它。有什么帮助吗?
答案 0 :(得分:214)
您可以使用TruncateTime的EntityFunctions方法将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)
我认为最好的方法就是这样:
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);
答案 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修剪回日期部分,而是增加了查询上限和用户<而不是<=