Search code examples
c#linqexpression-trees

Dynamic where clause to filter collection elements


I have a collection List<List<object>>, which I need to filter out based on wheater the List<object> collection contains given element. I was able to build the where clause, but i get the following Exception:

An exception of type 'System.InvalidOperationException' occurred in System.Core.dll but was not handled in user code Additional information: variable 'x' of type 'System.Collections.Generic.List`1[System.Object]' referenced from scope '', but it is not defined

I have found similar issues and i understand where the problem is, but i need help finding the solution.

Here is my code:

        protected override Expression<Func<List<object>, bool>> GetWhereClause()
        {
            var type = typeof(List<object>);
            var parameterExpression = Expression.Parameter(type, "x");                

            Expression expressionBody = null;
            if (Verified)
            {
                Expression<Func<List<object>, bool>> expression = x => x.Contains("Verified");
                expressionBody = expression.Body;
            }
            if (GoodMatch)
            {
                Expression<Func<List<object>, bool>> expression = x => x.Contains("Good Match");
                if (expressionBody != null)
                    expressionBody = Expression.Or(expressionBody, expression.Body);
                else
                    expressionBody = expression.Body;
            }
            //More conditions here
            if (expressionBody != null)
            {
                var whereClauseExp = Expression.Lambda<Func<List<object>, bool>>(expressionBody, parameterExpression);

                return whereClauseExp;
            }

            return null;
        } 

Now, this method generates the desired where clause, but when i try to apply it, i get the mentioned Exception.

        if (whereClause != null)
        {
            items = items.Where(whereClause.Compile());
            //
        }

Solution

  • I had a similar use case requiring dynamic where clauses and used Predicate Builder

    Using it, you could do something like:*

    private Expression<Func<List<T>, bool>> GetWhereClause<T>(T itemToFind){
            var predicate = PredicateBuilder.False<List<T>>();
    
            if(Verified) {
                predicate = predicate.And(p => p.Contains(itemToFind));
            }
    
            if(GoodMatch) {
                predicate = predicate.Or(p => p.Contains(itemToFind));
            }
    
            return predicate;
    }