Указанный член типа "Дата" не поддерживается в 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();