Я не могу найти, как сравнить дату, введенную пользователем, с датой в таблице, созданной EF6. Я использую LINQ Extensions для поиска в БД и попробовал несколько предложений, которые компилируются, но сбой во время выполнения.
Вход пользователя:
DateTime userdate;
DateTime.TryParse(search.Value, out userdate);
Попытки до сих пор:
a = dbContext.Messages.Where(x => x.Date.Date == userdate.Date); // doesn't compile
a = dbContext.Messages.Where(x => x.Date.Value.Date == userdate.Date); // error # 4
a = dbContext.Messages.Where(x => x.Date.ToString() == userdate.Date.ToString()); // issue #2
a = dbContext.Messages.Where(x => x.Date.Value.ToString() == userdate.Date.ToString()); // issue #2
a = dbContext.Messages.Where(x => Object.Equals(x.Date, userdate.Date)); // throws error #1
a = dbContext.Messages.Where(x => Object.Equals(x.Date.Date, userdate.Date)); // throws error #1
Я попытался найти это миллион раз и найти решения, которые компилируются, но всегда бросать ошибку при ее выполнении.
Была версия ToString()
которая сработала, но она сгенерировала длинную строку даты, например May 12, 2005 00:00:00
и попыталась превратить мою учетную запись в длинную дату, чтобы сравнить просто похоже, что она создавала бы слишком много накладные расходы при поиске по миллионам записей.
Я здесь не из идей.
Вопросы:
Невозможно передать тип "System.Nullable "'1 [[System.DateTime, mscorlib, Version = 4.0.0.0, Culture = neutral, PublicKeyToken = b77a5c561934e089]] 'для ввода" System.Object ". LINQ to Entities поддерживает только листинг EDM-примитивов или типов перечислений.
Не находит совпадений, даже с точным дате
Волшебно работает внезапно.
Указанный член типа "Дата" не поддерживается в LINQ to Entities. Поддерживаются только инициализаторы, сущности и свойства навигации сущности.
Окончательное решение. Основываясь на выбранном ответе, я обнаружил, что класс SqlFunctions имеет метод.DateDiff, который сопоставляется с функцией DateDiff T-SQL. Я использовал это, чтобы подсчитать количество дней между двумя датами и выбрать только те, которые вернули 0. Это позволило мне сравнить даты, не делая никаких преобразований на стороне SQL.
Некоторые операции.NET не могут быть неявно преобразованы в эквивалентные операции SQL, для этого вам необходимо использовать методы, представленные в System.Data.Entity.DbFunctions. В вашем конкретном примере вам следует попробовать использовать метод TruncateTime
вместо доступа к свойству .Date
экземпляра DateTime
.
Пример:
var date = userDate.Date;
dbSet.Where(x => DbFunctions.TruncateTime(x.Date) == date);
Изменение: альтернативно, SQL-сервер не обязательно поддерживает тот же диапазон для datetime
-values, что и.NET, поэтому, если ваш синтаксический анализ завершился с ошибкой, и вы получите DateTime.MinValue
это может быть не поддерживаемое значение datetime
на вашем SQL-сервере.
dbSet.Where(x => SqlFunctions.DateDiff("Day", x.Date.Value, userdate) == 0);
.. и это сработало. Вопрос теперь, так как я знаю, что это работает также. .Where(x => x.Date.Value == userdate.Date)
Есть ли различия в производительности?
Where
непосредственно вdbContext
а не в таблице в контексте, кстати ...)