Linq-to-SQL: объединение (объединение ИЛИ) нескольких фильтров «Содержит»?

У меня возникли проблемы с поиском лучшего способа сделать это, и я буду признателен за любую помощь.

По сути, я настраиваю фильтр, который позволяет пользователю просматривать историю элементов аудита, связанных с произвольным «фильтром» имен пользователей.

Источником данных является база данных SQL Server, поэтому я беру «источник» IQueryable. (либо прямая ссылка на таблицу из объекта контекста db, либо, возможно, IQueryable, полученный в результате дополнительных запросов), применяя фильтр WHERE, а затем возвращая результирующий объект IQueryable .... но я немного не понимаю, как это сделать выполнить ИЛИ с использованием этого подхода.

Я подумал о том, чтобы пойти по пути выражений, потому что я знаю, как их ИЛИ, но я не смог понять, как это сделать с помощью оценки типа «Содержит», поэтому в настоящее время я использую UNION, но я боюсь, что это может негативно повлиять на производительность, и мне интересно, может ли это дать мне именно то, что мне нужно, если другие фильтры (в дополнение к фильтрации имени пользователя, показанной здесь) добавляются в произвольном порядке.

Вот мой пример кода:

public override IQueryable<X> ApplyFilter<X>(IQueryable<X> source)
{
    // Take allowed values...
    List<string> searchStrings = new List<string>();

    // <SNIP> (This just populates my list of search strings)

    IQueryable<X> oReturn = null;

    // Step through each iteration, and perform a 'LIKE %value%' query
    string[] searchArray = searchStrings.ToArray();
    for (int i = 0; i < searchArray.Length; i++)
    {
        string value = searchArray[i];
        if (i == 0)
            // For first step, perform direct WHERE
            oReturn = source.Where(x => x.Username.Contains(value));
        else
            // For additional steps, perform UNION on WHERE
            oReturn = oReturn.Union(source.Where(x => x.Username.Contains(value)));
    }
    return oReturn ?? source;
}

Кажется, это неправильный способ делать что-то, но, похоже, он работает, Итак, мой вопрос первый, есть ли лучший способ сделать это? Кроме того, есть ли способ сделать «Содержит» или «Нравится» с выражениями?

(Отредактировано, чтобы исправить мой код: при откате к рабочему состоянию для публикации я, по-видимому, не откатился достаточно далеко достаточно :))

=========================================== ==

ETA: Согласно данному решению, вот мой новый код (на случай, если кто-то, читающий это, заинтересован):

public override IQueryable<X> ApplyFilter<X>(IQueryable<X> source)
{
    List<string> searchStrings = new List<string>(AllowedValues);

    // <SNIP> build collection of search values 

    string[] searchArray = searchStrings.ToArray();

    Expression<Func<X, bool>> expression = PredicateBuilder.False<X>();

    for (int i = 0; i < searchArray.Length; i++)
    {
        string value = searchArray[i];
        expression = expression.Or(x => x.Username.Contains(value));
    }
    return source.Where(expression);
}

(Одно предостережение, которое я заметил: в соответствии с примером PredicateBuilder пустая коллекция поисковых строк вернет false (false || value1 || ...), тогда как в моей исходной версии я предполагал, что пустой список должен просто переходить в нефильтрованный источник. По мере того, как я думал об этом больше, новая версия, кажется, имеет больше смысла для моих нужд , поэтому я принял это)

========================================== ===

5
задан Steven 21 December 2010 в 17:31
поделиться