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.