24 May, 2022

Dynamic Predicate Builder Not Passing Parameters of OR Clause to SQL Server

Are you using Predicate Builder to frame search query Or where clause for Linq to SQL or Entity Framework to SQL Server ? 

Many times we are into such situations where search request having multiple search criteria like first name, last name, userid etc, but search query should be issued only if user has passed or provided those values, if user or User interface (UI) has not supplied anything to your service, service should not issue those parameters in search or Where clause. There is useful library/class available to reduce the turnaround time. But there is great catch in that class.

 
    public static class PredicateBuilder
    {
        ///     
        /// Creates a predicate that evaluates to true. Use with mandatory Criteria
        ///     
        public static Expression> True() { return param => true; }

        ///     
        /// Creates a predicate that evaluates to false. Use where Criteria is optional
        ///     
        public static Expression> False() { return param => false; }
    ...
If you are suspecting that any param on right side would be optional or should run with OR Clause, you must use following syntax, Pay attention to PredicateBuilder.False
 
var predicate = PredicateBuilder.False();

 if (!string.IsNullOrEmpty(request.productName))
{
    predicate = predicate.Or(r => request.productName.Contains(r.Name!));
}

Now, if you simply perform F9 on "predicate" and print predicate.ToString() on F9 window you will see f => (((False OrElse Invoke(c => value(...which guarantees that expression on right side would get evaluated and passed to SQL server. 

 If accidentally we put PredicateBuilder.True with Or Expression, right side params are never passed to SQL Server by PredicateBuilder. 

Hope you enjoy this reading and this has saved your precious time :)

No comments: