Страницы

Поиск по вопросам

пятница, 14 февраля 2020 г.

LINQ to Entities does not recognize the method 'System.DateTime AddDays(Double)'

#c_sharp #entity_framework #linq



  Внимание! Это перевод вопроса Linq to EntityFramework
  DateTime.
  
  Также смотри близкий по смыслу вопрос: Linq to Entities не распознает
  метод


У меня есть приложение c# использующее Entity Framework.

Я делаю запрос к таблице Article, имеющей поле startDate и хочу получить записи из
базы, которые удовлетворяют условиям DateTime.Now > startDate и (startDate + period)
> DateTime.Now:

Context.Article
    .Where(p => p.StartDate < DateTime.Now)
    .Where(p => p.StartDate.AddDays(p.Period) > DateTime.Now)


При запуске этого кода я получаю ошибку:


  LINQ to Entities does not recognize the method 'System.DateTime AddDays(Double)'
method, and this method cannot be translated into a store expression.


Как это исправить?
    


Ответы

Ответ 1



Когда происходит выполнение Linq-запроса, ваши условия в where, которые записаны на языке c# должны быть преобразованы в SQL-запрос и в ошибке сообщается о том, что LINQ to Entities неизвестно, как преобразовывать AddDays из c# кода в код SQL. Есть два варианта решения этой проблемы. Первый вариант подразумевает, что вы отказываетесь от того, чтобы выполнять эти условия на сервере и перенесёте на клиент. Так как Linq To Objects знает, как обработать AddDays - то ошибка пропадёт: Context.Article.Where(p => p.StartDate < DateTime.Now) .ToList() .Where(p => p.StartDate.AddDays(p.Period) > DateTime.Now); Минусы этого подхода очевидны: вы качаете лишние данные с SQL-сервера в память клиента и эти расходы могут быть весьма значительны. Например, в данном примере когда нужно выбрать статьи за определённый промежуток времени вы должны будете сначала забрать всю таблицу к себе в память, а потом только уже отфильтровать. А вот если бы у вас запрашивался список статей какого-то определённого автора за интервал времени, то вероятно этой дополнительной нагрузкой для клиента можно было бы пренебречь. Второй вариант решения подразумевает, что у вас версия .Net 4.0 или выше и вы можете воспользоваться EntityFunctions.AddDays: Context.Article.Where(p => p.StartDate < DateTime.Now) .Where(p => EntityFunctions.AddDays(p.StartDate, p.Period) > DateTime.Now); В данном подходе sql-выражение выполняется на сервере, поэтому этот вариант решения является более предпочтительным. Разумеется, помимо AddDate в EntityFunctions есть и определения для других функций. В EF6 вместо EntityFunctions вам следует использовать аналог – DbFunctions, например для AddDays есть аналог. Это то, что касается стандартных классов .Net, которые присутствуют в фреймворке. Сходная ошибка может проявляться для ваших собственных функций, которые неизвестно как приводить к SQL на сервере.

Комментариев нет:

Отправить комментарий