Внимание! Это перевод вопроса 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.
Как это исправить?
Когда происходит выполнение 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 на сервере.
Апостиль в Лос-Анджелесе без лишних нервов и бумажной волокиты
Основные этапы разработки сайта для стоматологической клиники
Продвижение своими сайтами как стратегия роста и независимости