Сравнение дат в запросе с помощью LINQ

у меня есть запрос Linq, который возвращает тип var myQry

var myQry = from .....

Это большой linq возвращает все записи, которые мне нужно фильтровать дальше. В одном из моих условий if у меня есть фильтр, который работает так, чтобы проверить дату. Мне нужно проверить, содержит ли имя Введенное имя и точно соответствует дате рождения.

Я пробовал это, который скомпилирован и запущен, но не работал правильно

myQry.Where(x => x.FirstName.Contains(strName) && DateTime.Compare( x.BirthDt, searchDt)>=0).ToList()

затем я попробовал это, который дал бросил исключение "Аргументы DbArithmeticExpression должны иметь числовой общий тип"

myQry.Where(x => x.FirstName.Contains(strName) && (x.BirthDt- searchDt).Days == 0).ToList();

для такой ситуации, когда я использую предложение where в своем запросе, какой был бы лучший способ сделать сравнение дат? Какие операции не разрешены в предложении where запроса LinQ?

Спасибо за ваше время...

4 ответов


в этом случае вы можете использовать определенные функции SQL Server, используя методы из SqlMethods класса.

второй запрос может быть переписан как

myQry.Where(x => x.FirstName.Contains(strName) && 
    SqlMethods.DateDiffDay(x.BirthDt, searchDt) == 0).ToList()

который будет переведен на что-то вроде

SELECT ... FROM Table WHERE FirstName 
    LIKE '@p0' AND DATEDIFF(Day, BirthDt, @p1) = @p2

где P0, p1 и p2-параметры.


попробуйте это:

myQry.Where(x => x.FirstName.Contains(strName) &&
x.BirthDt.Date == searchDt.Date).ToList()

обратите внимание, что для работы выше, как BirthDt и searchDt должны быть допустимыми значениями DateTime. Теперь вы сравниваете только часть даты значений DateTime, отбрасывая часть времени.


Я согласен с Leniel Macaferi относительно обновления Where и сравнивать даты, а не даты и время. Для даты рождения, как правило, время рождения не имеет значения. Чтобы ответить на ваш второй вопрос

какие операции не разрешены в предложении where LinQ запрос?

Where() метод расширения, который работает на IEnumerable<T> или IQueryable<T>. Мы можем увидеть это, нажав F12 на Where чтобы взглянуть на источник код:

public static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate);

поддерживаемые операции называются предикатами. Предикат-это делегат, который принимает аргумент типа TSource и возвращает bool, сообщающий нам, является ли условие совпадением или нет. Это можно увидеть в коде выше во втором параметре:Func<TSource, bool> predicate

вы можете определить предикат, чтобы быть тем, что вы хотите. Пока он возвращает bool и принимает 1 параметр типа TSource.

это обычно достигается путем определения лямбда выражение, которое сделал для тебя Лениэль Макафери.


какие операции поддерживаются, зависит от ORM framework, (Nhibernate, EF и т.д.), Но в основном вы можете считать, что если метод, который вы используете, не имеет буквального перевода на SQL, очень вероятно, что он не будет поддерживаться.

вот почему оператор == поддерживается, но не DateTime.Compare метод или оператор - на DateTime не поддерживается, так как он не имеет четкого перевода.

всегда старайтесь придерживаться самого простого оператора и избегайте методов, если это все еще не удается, вам придется Google, если этот конкретный метод поддерживается вашим ORM.