Lambda Expressions and Search

Suppose I have a form that has the following:

Name: TextBox
Email: TextBox
Age: TextBox

now i want to get customer collection based on these filter text fields

so I want to use something like:

List<customer> customers = getCustomerswhere(c=>c.name == txtName.Text && Email == txtEmail.Text); 

now, of course, I don’t know what it will fill and that it will not be so

 if (txtName.Text.trim() != "") //something like c=>c.Name == txtName.text; if (txtEmail.Text.trim() != "") //something like and c=>c.Email == txtEmail.text; 

how i do it! I cannot concatenate lambda expressions, I know I can use dynamic expressions, but I think there is an easier way? any idea how to implement this?


ok I tried this:

  Func<Customer,bool > a = (bb) => bb.fullName == "asdfsd"; Func<Customer, bool> b = c => c.lastName == "sdas"; Func<Customer, bool> cc = c => a(c) && b(c); 

now another problem arises

im method going through CC to expects Expression<Func<T, bool>> expression

so it doesn’t work, gives me a compilation of time error can not convert between types!

+4
source share
4 answers

Here's how I implemented it:

  public class LambdaCriteries<T> : List<Expression<Func<T, bool>>> { public Expression<Func<T, bool>> GetFinalLambdaExpression() { var par = Expression.Parameter(typeof(T)); var intial = Expression.Invoke(this.First(),par); var sec = Expression.Invoke(this.Skip(1).First(),par); BinaryExpression binaryExpression = Expression.And(intial, sec); if (this.Count> 2) { foreach (var ex in this.ToList().Skip(2)) { binaryExpression = Expression.And(binaryExpression, Expression.Invoke(ex, par)); } return Expression.Lambda<Func<T, bool>>(binaryExpression,par); } else { return Expression.Lambda<Func<T, bool>>(binaryExpression,par); } } } 

and use it:

  if(txtId.text != "") criteries.Add(v => v.Id == int.Parse(txtId.text)); if(txtName.text != "") criteries.Add(v => v.Name == txtId.text); 

and final expression:

 var finalexp = criteries.GetFinalLambdaExpression(); 
+1
source

you can create several expressions like:

 var a = c => c.name == txtName.Text; var b = c => c.name == txtName.Text; 

and then combine them as follows:

 var result = c => a(c) && b(c); 
+2
source

Like this:

 Func<Customer, bool> predicate = c => true; if (txtName.Text.Trim() != "") predicate = Concatenate(predicate, c => c.Name == txtName.text); if (txtEmail.Text.Trim() != "") predicate = Concatenate(predicate, c => c.Email == txtEmail.text); static Func<T, bool> Concatenate(Func<T, bool> a, Func<T, bool> b) { return t => a(t) && b(t); } 

The Concatenate method must be a separate method because lambda expressions capture variables by reference.

Line

 predicate = c => predicate(c) && c.Name == txtName.text; 

will lead to a stack overflow because the predicate variable will always refer to the last immutable instance of the delegate that you assigned to it.

+2
source
 return Customers.Where(c => (txtName.Text.Trim() == "" || c.Name == txtName.Text) && (txtEmail.Text.Trim() == "" || c.Email == txtEmail.Text)); 

In other words, just put the condition “name” if the field “name” is filled, and put the condition “email” if the field “email” is filled.

Note that you can use the String.IsNullOrWhiteSpace method in .NET 4.0 instead of the Trim method you use.

+2
source

All Articles