Как я могу сравнить дату типа Nullable, используя введенную пользователем дату?

1

Я не могу найти, как сравнить дату, введенную пользователем, с датой в таблице, созданной 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 и попыталась превратить мою учетную запись в длинную дату, чтобы сравнить просто похоже, что она создавала бы слишком много накладные расходы при поиске по миллионам записей.

Я здесь не из идей.

Вопросы:

  1. Невозможно передать тип "System.Nullable "'1 [[System.DateTime, mscorlib, Version = 4.0.0.0, Culture = neutral, PublicKeyToken = b77a5c561934e089]] 'для ввода" System.Object ". LINQ to Entities поддерживает только листинг EDM-примитивов или типов перечислений.

  2. Не находит совпадений, даже с точным дате

  3. Волшебно работает внезапно.

  4. Указанный член типа "Дата" не поддерживается в LINQ to Entities. Поддерживаются только инициализаторы, сущности и свойства навигации сущности.

Окончательное решение. Основываясь на выбранном ответе, я обнаружил, что класс SqlFunctions имеет метод.DateDiff, который сопоставляется с функцией DateDiff T-SQL. Я использовал это, чтобы подсчитать количество дней между двумя датами и выбрать только те, которые вернули 0. Это позволило мне сравнить даты, не делая никаких преобразований на стороне SQL.

  • 2
    Итак, вы говорите, что есть ошибка ... что это за ошибка ?
  • 0
    (Странно использовать Where непосредственно в dbContext а не в таблице в контексте, кстати ...)
Показать ещё 6 комментариев
Теги:
datetime
entity-framework
entity-framework-6

1 ответ

3
Лучший ответ

Некоторые операции.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-сервере.

  • 0
    Поэтому я посмотрел документацию для System.Data.Entity.DbFunctions и нашел класс SqlFunctions. В нем много функций, которые я часто использую при написании T-SQL, что помогает мне переходить с кода .NET на T-SQL. Используя это, я попытался dbSet.Where(x => SqlFunctions.DateDiff("Day", x.Date.Value, userdate) == 0); .. и это сработало. Вопрос теперь, так как я знаю, что это работает также. .Where(x => x.Date.Value == userdate.Date) Есть ли различия в производительности?
  • 0
    Спасибо за вашу помощь. Я закончил тем, что использовал функцию, указанную выше. Я обнаружил, что для этого не требуется никакого преобразования на стороне SQL, что должно повысить производительность.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню