This is the tutorial I'm following to learn Expression Tree.
I've more than 35 columns to display, but the user can chose to display 10 columns at once. So one the user type something in the search box, I want to search only the columns that are visible to the user.
SELECT FirstName, LastName, Address, ..., State
FROM Students
WHERE Id == @Id col1 AND (
FirstName LIKE '%@searchText%' OR
LastName LIKE '%@searchText%' OR
Address LIKE '%@searchText%' OR
...
State LIKE '%@searchText%')
Back to Linq, this is how I'm trying to accomplish it:
var result = db.Students
.Where(GetPredicate(id, listOfColumns))
.ToList();
This the private method:
private Expression<Func<Student, bool>> GetPredicate(int id, List<string> listOfColumns)
{
ParameterExpression pe = Expression.Parameter(typeof(Student), "s");
Expression left0 = Expression.Property(pe, "Id");
Expression right0 = Expression.Constant(id);
Expression e0 = Expression.Equal(left0, right0);
//Here ... omitted code because it's not working...
//
var expr = Expression.Lambda<Func<Student, bool>>(e0, new ParameterExpression[] { pe });
return expr;
}
As it is above, it's working just fine. However, the reason I even wrote this method was to be able to filter only by the user-selected columns.
I want to be able to compose based on the column that are visible in the UI.
if(!string.IsNullOrEmpty(searchText))
{
foreach (string columnName in columnList)
{
Expression col = Expression.Property(pe, columnName);
Expression left = Expression.Call(pe, typeof(string).GetMethod("Contains"));
Expression right = Expression.Constant(searchText);
Expression e = Expression.IsTrue(left, right);
}
}
I'm completely lost. I know that I need to access the Contains method of the string class then I don't know what next. The Idea is to get something like this:
Where(d => d.Id == id && (d.FirstName.Contains(searchText)
|| d.LastName.Contains(searchText)
|| ...
|| d.State.Contains(searchText)))
Thanks for helping
I like the PredicateBuilder class for stuff like this scenario:
Code using this would look like:
At the end, use the PredicateBuilder instance as arguments to your Where operator in the Linq query.
You are pretty close, except constructing the call of
Contains
does not have a right side:Once you have your call expressions, combine them with
OrElse
to produce the body of your lambda. You can do it with loops, or you can use LINQ: