5

I have an entity like this:

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

I want to implement a search for keywords on the Name property so that they're OR'ed. In other words, a search for:

spoon knife fork

will search for spoon or knife or fork in the Name property. I introduced a new method for PredicateBuilder on Product that looks like this:

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;
}

And I'm using it like this in one of my methods for a web service:

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

The problem I'm running into is that the user may choose not to do a keyword search, in which case the keywords array will be empty. If I start with PredicateBuilder.True<Product>(), I get a list of all Products, regardless of what keywords I put in. If I start with PredicateBuilder.False<Product>(), it works if the user inputs keywords, but if not, then the return list is empty because everything matched false.

How do I fix this in order to get my desired behavior, which is to return a list of all Products if no keyword was provided, and return a list of only the Products that matches the keywords if they were provided? I know I can do a check to see if the keywords array is empty before I do any processing, but if at all possible, I'd like PredicateBuilder to handle this case automatically.

Daniel T.
  • 37,212
  • 36
  • 139
  • 206

1 Answers1

3
var predicate = (keywords.Count() > 0)
    ? PredicateBuilder.False<Product>()
    : PredicateBuilder.True<Product>();
Kris Ivanov
  • 10,476
  • 1
  • 24
  • 35
  • Yeah, that's best, but he specifically asked for a way without checking if the list is empty. – Jacob Feb 02 '11 at 02:42
  • Well, optimally I'd like to do that. I did `if (!keywords.Any()) return PredicateBuilder.True()`, but I wanted to see if there were other solutions out there. – Daniel T. Feb 02 '11 at 02:46
  • that is optimal, what is the problem checking for empty array? – Kris Ivanov Feb 02 '11 at 02:49