2010-11-10 3 views
85

В моем приложении я использую Entity Framework.Linq to EntityFramework DateTime

Моей таблица

-Article 
-period 
-startDate 

мне нужна запись, которые соответствуют =>DateTime.Now > startDate and (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.

+0

Какой тип 'period'? 'AddDays' - неправильная функция, если это' double'. –

+0

Тип периодов is int – Yucel

ответ

160

При использовании LINQ to Entity Framework ваши предикаты внутри предложения Where преобразуются в SQL. Вы получаете эту ошибку, потому что нет перевода на SQL для DateTime.Add(), что имеет смысл.

Быстрая работа вокруг будет читать результаты первого Где утверждение в памяти, а затем использовать LINQ к объектам для завершения фильтрации:

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

Вы также можете попробовать метод EntityFunctions.AddDays если вы с .NET 4.0:

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

Примечание: В EF 6 это теперь System.Data.Entity.DbFunctions.AddDays.

+32

Это опасный обход, что произойдет, если ToList() вернет огромное количество данных? –

+0

@Stefan P. - Тогда первое утверждение будет читать огромное количество данных в памяти. Второй метод должен быть хорошим, но доступен только с .NET 4.0. –

+6

Спасибо за EntityFunctions.AddDays tip Я использую EF .net 4.0, но я не знал об EntityFunctions, посмотрю на него. –

3

Как насчет вычитая 2 дня от DateTime.Now:

Context.Article 
.Where(p => p.StartDate < DateTime.Now) 
.Where(p => p.StartDate > DateTime.Now.Subtract(new TimeSpan(2, 0, 0, 0))) 

Честно говоря, я не уверен, что вы пытаетесь достичь, но это может работать

+0

Статьи начнут отображаться на StartDate и заканчиваться после x (период) дней. Это то, что я пытаюсь сделать. Второе решение Джастина Нисснера работало очень хорошо для того, что я хочу видеть. – Yucel

+1

У меня такая же ошибка с помощью Subtract! –

71

Я думаю, что это то, что в прошлом ответ пытается предложить, но вместо того, чтобы добавить дней p.startdat (то, что не может быть преобразован в SQL Statement), почему бы не сделать что-то, что может быть приравнено к SQL:

var baselineDate = DateTime.Now.AddHours(-24); 

something.Where(p => p.startdate >= baselineDate) 
+7

Это гораздо лучший ответ, чем принятый ответ с большим количеством голосов. Это проще, безопаснее и эффективнее. –

+1

@Adrian Carr - Это может быть лучше для этого варианта использования, но не для решения 'EntityFunctions'. Здесь второй операнд не извлекается из другого объекта в запросе и может быть вычислен до запроса. Если оба операнда были найдены в db, решение 'EntityFunctions' по-прежнему будет подходящим, в то время как решение этого ответа больше не будет работать. –

1

Если вам нужно, чтобы ваше выражение переводилось на SQL, вы можете попробовать использовать

System.Data.Entity.Core.Objects.AddDays метод.

Фактически обозначен как устаревший, но он работает. Его следует заменить System.Data.Entity.DbFunctions.AddDays, но я не могу найти его ...

+0

Это добавляет ничего, кроме принятого ответа от 4 лет до этого! –

+0

@AndrewHarris также мой ответ 4 года назад ответ. В первой версии ответа перед To Where появился ToList (=> материализация данных) (см. Первый комментарий ответа). – bubi

Смежные вопросы