LINQ: добавление предложения where только тогда, когда значение не равно null

Попробуйте HttpUnit, хотя Вы, вероятно, закончите тем, что писали автоматизированные тесты, которые являются большим количеством 'интеграционных тестов' (модуля), чем 'модульные тесты' (единого класса).

22
задан Henry 26 April 2011 в 08:30
поделиться

8 ответов

Вы можете написать это как

IQueryable query = from staff in dataContext.Staffs;
query = from staff in query where (name1 != null && staff.name == name1);

Таким образом, вторая часть вашего состояния не будет оцениваться, если ваше первое условие оценивается как ложное

Обновление:
, если вы напишите

IQueryable query = from staff in dataContext.Staffs;
    query = from staff in query where (name1 == null || staff.name == name1);

и name1 будет нулевым, вторая часть вашего условия не будет оцениваться, так как или условие требует только одного условия для возврата true

плз смотрите это ссылка для более подробной информации

18
ответ дан 29 November 2019 в 04:53
поделиться

Лучший способ сделать это - создать себе метод расширения , который будет принимать условное выражение и выражение where. Если условие истинно, то оно будет использовать выражение where, иначе оно не будет его использовать. Это может значительно очистить ваш код, устраняя необходимость в операторах if.

public static class LinqExtensions
{
    public static IQueryable<T> WhereIf<T>(this IQueryable<T> query, bool condition, Expression<Func<T, bool>> whereClause)
    {
        if (condition)
        {
            return query.Where(whereClause);
        }
        return query;
    }
}

Теперь вы можете написать свой код так:

IQueryable<Staffs> query = dataContext.Staffs.AsQueryable().WhereIf(name1 != null, x => x.Name == name1);
5
ответ дан 29 November 2019 в 04:53
поделиться

Я видел этот шаблон в стандартном SQL, и он кажется полезным, если у вас есть несколько параметров, которые могут быть NULL. Например:

SELECT * FROM People WHERE ( @FirstName IS NULL OR FirstName = @FirstName )
                       AND ( @LastName IS NULL OR LastName = @LastName )

Если вы видите это в LINQ, возможно, они просто слепо перевели свои старые SQL-запросы.

1
ответ дан 29 November 2019 в 04:53
поделиться

Мне нравится использовать выражение, например,

    Expression<Func<Persons, bool>> expresionFinal = c => c.Active == true;

    if (DateBirth.HasValue)
                {
                    Expression<Func<Persons, bool>> expresionDate = c => (EntityFunctions.TruncateTime(c.DateBirth) == DateBirth);
                    expresionFinal = PredicateBuilder.And(expresionFinal, expresionDate);
                }

IQueryable query = dataContext.Persons;
 query = query.Where(expresionFinal);
1
ответ дан 29 November 2019 в 04:53
поделиться

Итак, я попробовал метод расширения .Where(..., x => ...), приведенный здесь в качестве ответа, но он не работает с Entity Framework, поскольку Linq To Entities не знает, как перевести его в TSQL.

Итак, вот мое решение, включающее мой Func:

Expression<Func<SomeEfPoco, bool>> columnBeingFilteredPredicate = x => true; // Default expression to just say yes
if (!string.IsNullOrWhiteSpace(someColumnBeingFilteredValue))
{
    columnBeingFilteredPredicate = x => x.someColumnBeingFiltered == someColumnBeingFilteredValue;
}

_context.SomeEfPocos.Where(x => ..... &&
            ..... &&
            ..... &&)
.Where(columnBeingFilteredPredicate);

someColumnBeingFilteredValue в моем случае - строковый параметр в методе инкапсуляции со значением по умолчанию NULL.

1
ответ дан 29 November 2019 в 04:53
поделиться

LINQ отличается по ряду других причин (не по этим причинам), LINQ - это способ получить данные «более быстрым способом» с помощью небольшого кода и, по возможности, четкой трески, есть много преимуществ LINQ:

  1. Упрощает преобразование данных в объекты. Я уверен, что вы слышали, что термин «несоответствие импедансов» используется довольно часто, а это означает, что LINQ сокращает объем работы, которую вы должны выполнить для преобразования между объектно-ориентированным кодом и парадигмами данных, такими как иерархические, плоские файлы, сообщения, реляционные и многое другое. Это не устраняет «несоответствие импедентности», потому что вы все равно должны рассуждать о своих данных в их исходной форме, но мост отсюда туда (IMO) намного короче.

  2. Общий синтаксис для всех данных. Как только вы изучите синтаксис запроса, вы можете использовать его с любым поставщиком LINQ. Я думаю, что это гораздо лучшая парадигма развития, чем Вавилонская башня, которая выросла за годы с технологиями доступа к данным. Конечно, у каждого провайдера LINQ есть свои уникальные нюансы, но базовый подход и синтаксис запросов одинаковы.

  3. Строго типизированный код. Синтаксис запроса C # (или VB.NET) является частью языка, и вы кодируете с помощью типов C #, которые переводятся в то, что понимает поставщик. Это означает, что вы получаете производительность, когда ваш компилятор обнаруживает ошибки на более ранних этапах жизненного цикла разработки, чем где-либо еще. Конечно, многие ошибки в синтаксисе хранимых процедур вызывают ошибки при сохранении, но LINQ является более общим, чем SQL Server. Вы должны подумать обо всех других типах источников данных, которые генерируют ошибки времени выполнения, потому что их запросы формируются с помощью строк или какого-либо другого свободно типизированного механизма.

  4. Интеграция провайдера. Собрать источники данных очень легко. Например, вы можете использовать LINQ to Objects, LINQ to SQL и LINQ to XML вместе для некоторых очень сложных сценариев. Я думаю, что это очень элегантно.

  5. Сокращение в работе. До LINQ я потратил много времени на создание DAL, но теперь мой DataContext - это DAL. Я также использовал OPF, но теперь у меня есть LINQ, который поставляется с несколькими поставщиками в комплекте и многими другими сторонними поставщиками, что дает мне преимущества от моих предыдущих пунктов. Я могу настроить LINQ to SQL DataContext за минуту (так быстро, как мой компьютер и IDE могут поддерживать скорость).

  6. Производительность в общем случае не становится проблемой. В наши дни SQL Server довольно хорошо оптимизирует запросы, как и хранимые процедуры. Конечно, все еще есть случаи, когда хранимые процедуры необходимы по соображениям производительности. Например, я нашел более разумным использовать хранимый процесс, когда у меня было несколько взаимодействий между таблицами с дополнительной логикой внутри транзакции. Затраты на связь при попытке выполнить ту же задачу в коде в дополнение к вовлечению кода DTC в распределенную транзакцию сделали выбор хранимого процесса более убедительным. Однако для запроса, который выполняется в одном операторе, LINQ - мой предпочтительный выбор, потому что даже если бы был небольшой выигрыш в производительности от хранимого процесса, преимущества в предыдущих точках (IMO) имеют больший вес.

  7. Встроенная безопасность. Одной из причин, по которой я предпочел хранимые процедуры до LINQ, было то, что они принудительно использовали параметры, помогая уменьшить атаки с использованием SQL-инъекций. LINQ to SQL уже параметризует ввод, который так же безопасен.

  8. LINQ является декларативным. Большое внимание уделяется работе с LINQ to XML или LINQ to SQL, но LINQ to Objects невероятно мощный. Типичным примером LINQ to Objects является чтение элементов из строки []. Однако это всего лишь маленький пример. Если вы думаете обо всех коллекциях IEnumerable (вы также можете запросить IEnumerable), с которыми вы работаете каждый день, возможностей у вас много. поиск в элементе управления ASP.NET ListBox для выбранных элементов, выполнение операций над множествами (например, Union) в двух коллекциях, или итерация по списку и запуск лямбда-выражения в ForEach каждого элемента. Как только вы начнете мыслить в LINQ, который носит декларативный характер, вы обнаружите, что многие из ваших задач более просты и интуитивно понятны, чем императивные методы, которые вы используете сегодня.

Я мог бы продолжить, но я бы остановился на этом. Надеемся, что это даст более позитивное представление о том, как вы могли бы быть более продуктивным с LINQ, и, возможно, посчитаете его полезной технологией в более широкой перспективе.

1
ответ дан 29 November 2019 в 04:53
поделиться

Нет, я не совсем согласен с вами. здесь вы просто дали простую логику

if(name1 != null)
// do your stuff

, но что произойдет, если вы сделаете что-то другое с именем1, которое имеет нулевое значение .. !! Хорошо, теперь рассмотрим эту ситуацию. В этом примере вы показываете, как обрабатывать возможные нулевые значения в исходных коллекциях. Коллекция объектов, такая как IEnumerable<T>, может содержать элементы с нулевым значением. Если исходная коллекция имеет значение NULL или содержит элемент со значением NULL, а ваш запрос не обрабатывает значения NULL, при выполнении запроса будет выдано NullReferenceException.

Вероятно, это может быть проблемой ...

0
ответ дан 29 November 2019 в 04:53
поделиться

Для EF Core я разбил это следующим образом:

IQueryable<Partners> recs = contextApi.Partners;
if (status != -1)
{
   recs = recs.Where(i => i.Status == status);
}
recs = recs.OrderBy(i => i.Status).ThenBy(i => i.CompanyName);
foreach (var rec in recs)
{
}

Я должен был быть явным с моим набором текста вместо того, чтобы полагаться на var.

0
ответ дан 29 November 2019 в 04:53
поделиться
Другие вопросы по тегам:

Похожие вопросы: