Ошибка 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();
Другие вопросы по тегам