Сравнение дат в запросе с помощью 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.