Указанный член типа "Дата" не поддерживается в LINQ to Exities Exception
Я получил исключение при выполнении следующих утверждений.
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 );
Exception
The specified type member 'Date' is not supported in LINQ to Entities. Only initializers, entity members, and entity navigation properties are supported.
Я знаю, что такое исключение, но я не знаю, как избавиться от него. Любая помощь?
Ответы
Ответ 1
LINQ to Entities не может переводить большинство методов .NET Date (включая использование кастинга) в SQL, поскольку нет эквивалентного SQL.
Решение состоит в том, чтобы использовать методы Date вне оператора LINQ, а затем передать значение. Похоже, что Convert.ToDateTime(rule.data).Date вызывает ошибку.
Дата вызова в свойстве DateTime также не может быть переведена на 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
Вы можете использовать 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);
Обновление: EntityFunctions
устарело в EF6, используйте DbFunctions.TruncateTime
Ответ 3
Для EF6 вместо этого используйте DbFunctions.TruncateTime(mydate).
Ответ 4
"EntityFunctions.TruncateTime" или "DbFunctions.TruncateTime" в ef6 работает, но у него есть некоторые проблемы с производительностью в Big Data.
Я думаю, что лучший способ - действовать следующим образом:
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 );
это лучше, чем использовать части даты. потому что запрос выполняется быстрее в больших данных.
Ответ 5
Попробуйте использовать
return jobdescriptions.AsEnumerable()
.Where(j => j.JobDeadline.Date == Convert.ToDateTime(rule.data).Date );
AsEnumerable()
переключает контекст запроса из LINQ в Entities в LINQ to Objects, поэтому условие не преобразуется в SQL
Ответ 6
Что это значит, что LINQ to SQL не знает, как превратить свойство Date
в выражение SQL. Это связано с тем, что свойство Date
структуры DateTime
не имеет аналога в SQL.
Ответ 7
Это сработало для меня.
DateTime dt = DateTime.Now.Date;
var ord = db.Orders.Where
(p => p.UserID == User && p.ValidityExpiry <= dt);
Источник: Форумы Asp.net
Ответ 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
Вы можете получить Enum как:
DateTime todayDate = DateTime.Now.Date; var check = db.tableName.AsEnumerable().Select(x => new
{
Date = x.TodayDate.Date
}).Where(x => x.Date == todayDate).FirstOrDefault();