Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PredicateBuilder cannot convert to IQueryable?

i have a function:

private IEnumerable<Promotion> MatchesKeyword(IEnumerable<Promotion> list, String keyword)
{
   ...snip...
}

which right now performs a LINQ query:

private IEnumerable<Promotion> MatchesKeyword(IEnumerable<Promotion> list, String keyword)
{
   return list.Where(item => item.Name.ContainsText(keyword)
      || item.Description.ContainsText(keyword)
      ...snip...
   );
}

This code works well enough.

But i need to convert it to use a PredicateBuilder:

private IEnumerable<Promotion> MatchesKeyword(IEnumerable<Promotion> list, String keyword)
{
   var predicate = PredicateBuilder.False<Promotion>();     

   predicate = predicate.Or(item => item.Name.ContainsText(keyword)
         || item.Description.ContainsText(keyword)
         ...snip...
   );

   return list.Where(predicate);
}

Which, strangely, doesn't compile. The failing line is:

return list.Where(predicate);

You can take your pick of the errors:

  • Instance argument: cannot convert from 'System.Collections.Generic.IEnumerable' to 'System.Linq.IQueryable'
  • 'System.Collections.Generic.IEnumerable' does not contain a definition for 'Where' and the best extension method overload 'System.Linq.Enumerable.Where(System.Collections.Generic.IEnumerable, System.Func)' has some invalid arguments
  • Argument 2: cannot convert from 'System.Linq.Expressions.Expression>' to 'System.Func'

What's the problem? IEnumerable goes in, IEnumerable comes out.

i'll be honest, i read the page on PredicateBuilder and i don't understand any of it.


A hint of why i need to change to PredicateBuilder is:

private IEnumerable<Promotion> MatchesKeyword(IEnumerable<Promotion> list, String keyword)
{
   var predicate = PredicateBuilder.False<Promotion>();     

   predicate = predicate.Or(item => item.Name.ContainsText(keyword)
         || item.Description.ContainsText(keyword)
         ...snip...
   );

   DateTime dt = TryStrToDate(keyword);
   if (dt)
       predicate = predicate.Or(item => item.PromotionDate == dt);

   return list.Where(predicate);
}

...not that i need a reason, problem, practical example, or research effort to ask a question.

like image 417
Ian Boyd Avatar asked Jan 30 '12 16:01

Ian Boyd


1 Answers

PredicateBuilder needs an IQueryable<T> to do its magic. Just change the last line in your example to

return list.AsQueryable().Where(predicate);

to make it work.

like image 122
afrischke Avatar answered Oct 13 '22 22:10

afrischke