LINQ PredicateBuilder несколько ИЛИ, начиная с PredicateBuilder.True <> - PullRequest
4 голосов
/ 02 февраля 2011

У меня есть такая сущность:

public class Product()
{
    public string Name { get; set; }
}

Я хочу реализовать поиск по ключевым словам в свойстве Name, чтобы они имели ИЛИ.Другими словами, поиск:

вилка для ложки

будет искать ложка или нож или fork в свойстве Name.Я ввел новый метод для PredicateBuilder для Product, который выглядит следующим образом:

public static Expression<Func<Product, bool>> ContainsKeywords(params string[] keywords)
{
    var predicate = PredicateBuilder.True<Product>();

    foreach (var keyword in keywords)
    {
        var temp = keyword;
        predicate = predicate.Or(x => x.Name.Contains(temp));
    }

    return predicate;
}

И я использую его следующим образом в одном из моих методов для веб-службы:

var keywords = Request.QueryString["q"].Split(' ');
var products = Repo.GetAll<Product>(); // get all the products from the DB
products = products.Where(Product.ContainsKeywords(keywords));

Проблема, с которой я сталкиваюсь, заключается в том, что пользователь может отказаться от поиска по ключевым словам, и в этом случае массив keywords будет пустым.Если я начну с PredicateBuilder.True<Product>(), я получу список всех Products, независимо от того, какие ключевые слова я ввел. Если я начну с PredicateBuilder.False<Product>(), это будет работать, если пользователь вводит ключевые слова, но если нет, то список возвратапусто, потому что все соответствует false.

Как это исправить, чтобы получить желаемое поведение, а именно: вернуть список всех Products, если не было указано ключевое слово, и вернуть списоктолько Products, который соответствует ключевым словам, если они были предоставлены?Я знаю, что могу проверить, пуст ли массив ключевых слов перед выполнением какой-либо обработки, но, если это вообще возможно, я бы хотел, чтобы PredicateBuilder автоматически обработал этот случай.

1 Ответ

2 голосов
/ 02 февраля 2011
var predicate = (keywords.Count() > 0)
    ? PredicateBuilder.False<Product>()
    : PredicateBuilder.True<Product>();
...