C # predicate list passed to Linq Where clause

I have a long Linq Where clause that I would like to populate with a predicate list.

 List<Expression<Func<Note, bool>>> filters = new List<Expression<Func<Note, bool>>>(); filters.Add(p => p.Title != null && p.Title.ToLower().Contains(searchString)); filters.Add(p => p.Notes != null && p.Notes.ToLower().Contains(searchString)); filters.Add(GlobalSearchUser((List < User > users = new List<User>() { p.user1, p.user2, p.user3, p.user4 }), searchString)); notes = dataAccess.GetList<Note>(pn => pn.ProjectVersionID == projectVersionID, filterExtensions.ToArray()) .Where(filters.ToArray()).Take(10).ToList(); 

However, I get this error:

cannot convert from 'System.Linq.Expressions.Expression<System.Func<project.Contracts.DTOs.Note,bool>>[]' to 'System.Func<project.Contracts.DTOs.Note,bool>'

What a mistake in the .where clause. Pulling a compilation is just fine.

+7
c # linq where predicate
source share
4 answers

You need to sort through the filters and run a test on each of them.

You can do this with linq, like this, to return true if any of your filters:

 .Where(p => { foreach(f in filters) if (f(p) == true) return(true); return(false)}) 

or like this to return true if all of your filters are true:

 .Where(p => { foreach(f in filters) if (f(p) == false) return(false); return(true)}) 
+3
source share

There are at least two errors in the code:

 List<Expression<Func<Note, bool>>> filters = new List<Expression<Func<Note, bool>>>(); 

change it to

 List<Func<Note, bool>> filters = new List<Func<Note, bool>>(); 

You don't need Expression trees here. You are using IEnumerable<> , not IQueryable<>

 notes = dataAccess.GetList<Note>(pn => pn.ProjectVersionID == projectVersionID, filterExtensions.ToArray()) .Where(filters.ToArray()).Take(10).ToList(); 

There .Where() takes one predicate at a time. You could:

 notes = dataAccess.GetList<Note>(pn => pn.ProjectVersionID == projectVersionID, filterExtensions.ToArray()) .Where(x => filters.All(x)).Take(10).ToList(); 

or various other solutions, for example:

 var notesEnu = dataAccess.GetList<Note>(pn => pn.ProjectVersionID == projectVersionID, filterExtensions.ToArray()) .AsEnumerable(); foreach (var filter in filters) { notesEmu = notesEmu.Where(filter); } notes = notesEnu.Take(10).ToList(); 

Because all .Where() conditions are implicitly in && .

+5
source share

I think that the excellent answer from Hogan can be simplified and shortened a bit using the Linq Any and All methods.

To get items that satisfy all the conditions:

 var resultAll = listOfItems.Where(p => filters.All(f => f(p))); 

And to get items that satisfy any condition:

 var resultAny = listOfItems.Where(p => filters.Any(f => f(p))); 
+4
source share

You cannot just pass an array of predicates to the where method. You need to either iterate over the array, and continue calling Where() for each expression in the array, or find a way to combine them all together into one expression and use this. You want to use LinqKit if you are following the second route.

0
source share

All Articles