Ошибка Linq to Entities Datetime
У меня есть следующий код
var dates = query.Select(
x => DateTime.ParseExact(x.Date, "yyyy-MM", CultureInfo.InvariantCulture));
var minDate = dates.Min(x => x);
Но когда я выполняю это, я получаю исключение
System.Data.Entity.dll, но не был обработан в коде пользователя
Дополнительная информация: LINQ to Entities не распознает метод метода System.DateTime ParseExact(System.String, System.String, System.IFormatProvider), и этот метод нельзя преобразовать в выражение хранилища.
Что я делаю неправильно? И как я могу это исправить?
5 ответов
Что ж, ошибка на самом деле совершенно ясна. В Linq нет преобразования сущностей ParseExact в SQL.
Помните, что Entity Framework под крышками преобразует запрос в команду SQL или набор команд. Если EF не знает, как что-то перевести, он выдает эту ошибку.
Одним из возможных решений, хотя и не очень эффективным, является преобразование IQueryable в IEnumerable, что позволит вам выполнить инструкцию.
var dates = query.ToList().Select(
x => DateTime.ParseExact(x.Date, "yyyy-MM", CultureInfo.InvariantCulture));
Если даты в БД представлены в виде строк в формате "гггг-ММ", вы можете выполнить запрос на основе сортировки строк и преобразовать результат в DateTime:
var minDateString = query.Select(x => x.Date).Min();
var minDate = DateTime.ParseExact(
minDateString,
"yyyy-MM",
CultureInfo.InvariantCulture
);
Многие системы полагаются на естественное упорядочение строк "гггг-ММ-дд чч: мм: сс", вы также можете легко рассчитывать на подмножество этого упорядочения.
Боюсь, тебе придется загрузить все свои string
представления значений времени данных из БД в память:
var dates = query.Select(x => x.Date).ToList();
и выполните синтаксический анализ и min как запрос LINQ to Objects:
var min = query.Min(x => DateTime.ParseExact(x, "yyyy-MM", CultureInfo.InvariantCulture));
Если в вашей БД установлено свойство и x.Date
было DateTime
Вы могли бы сделать:
var dates = query.Select(x => x.Date);
var min = dates.Min();
который будет переведен в правильный запрос SQL и пусть MIN()
рассчитываться по базе данных, поэтому вам не придется загружать все данные в память приложения.
LINQ to Entities принимает ваш запрос LINQ и преобразует его в код SQL, который он затем выполняет для базы данных. Это означает, что код, который вы пишете, должен быть в состоянии преобразовать в код SQL. Нет способа конвертировать DateTime.ParseExact в код SQL, отсюда и исключение. Вам нужно будет оценить запрос LINQ to Entities, вызвав ToArray, а затем вы можете выполнить второй запрос LINQ to Objects, и он поймет DateTime.ParseExact.
Преобразование даты и времени в формат даты и времени БД:
obj.dt = TimeZoneInfo.ConvertTimeFromUtc((DateTime)obj.dt, TimeZoneInfo.FindSystemTimeZoneById("India Standard Time"));
Это простой способ сравнить дату без времени. Просто используйте следующий код:
_DBcontext.YourModelName.AsQueryable().Where(x=> x.CREATED_DATE.Date == dt.Date).toList();