Dynamic construction of lambda expressions

So, I started creating a small test application for testing lambda expressions. I found some examples here and elsewhere, but I just don't get them.

Can someone explain to me how to build an expression using text fields or any other variables?

My test list

List<People> lPeople = new List<People> { new People { Name= "Jean", LastName = "Borrow", Age= 21 } , new People { Name= "Dean", LastName = "Torrow", Age= 20 } }; 

Working lambda expression

 IEnumerable<People> result = lPeople.Where(p => p.Age < 21); dgv_1.DataSource = result.ToList(); dgv_1.Update(); 

How can I build expressions dynamically?

Something like lPeople.Where(p => p.LastName == Textbox.Text); (which of course does not work)

Thanks!

Edit: added some code to the solution below

 Int32 iAge; Boolean bSuc = Int32.TryParse(tb_filter_age.Text, out iAge); if (!bSuc) { iAge = 0; } 
+4
source share
6 answers

"which of course doesn't work"

What happens when you try? In appearance, this is what I do all the time.

To switch operations based on ComboBox with an operator:

 int age = int.Parse(textBoxAge.Text); IEnumerable<People> result; if (comboBoxOperator.Text == "=") result = lPeople.Where(p => p.Age == age); else if (comboBoxOperator.Text == "<") result = lPeople.Where(p => p.Age < age); else result = lPeople.Where(p => p.Age > age); dgv_1.DataSource = result.ToList(); dgv_1.Update(); 

Code that converts the age string to int will generate if the user enters something that cannot be converted. Take a look at TryParse to avoid exceptions.

+5
source

Try the predicate builder at http://www.albahari.com/nutshell/predicatebuilder.aspx

I used it to create an advanced search in which the user could add additional search criteria.

+5
source

You can use the Linq Dynamic Query Library to accomplish this. See the following blog post from Scott Guthrie for more information:

http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx

+2
source

Your example lambda expression will work. How dynamic do you need it? If you have a static filter interface to apply to the collection, you can create code similar to the following:

 IEnumerable<People> result = lPeople; if (txtLastName.Text.Trim().Length != 0) result = result.Where(p => p.LastName == txtLastName.Text); if (chkSeniors.Checked) result = result.Where(p => p.Age >= 65); dgv_1.DataSource = result.ToList(); dgv_1.Update(); 

If you want the consumer of your data source to use truly dynamic expressions (giving them the ability to select other fields for filtering and the expressions used), this is a more complex function to implement using the predicate tool or LINQ expressions.

+2
source

There should be nothing wrong with the way you do it. I created a simple Windows Forms application with TextBox , a Button and a DataGridView (with the names textBox1 , button1 and dgv_1 respectively.)

Here is the code I used for the Form1.cs file, which worked as expected:

 public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { List<People> lPeople = new List<People> { new People { Name= "Jean", LastName = "Borrow", Age= 21 } , new People { Name= "Dean", LastName = "Torrow", Age= 20 } }; IEnumerable<People> result = lPeople.Where(p => p.Name == textBox1.Text); dgv_1.DataSource = result.ToList(); dgv_1.Update(); } } public class People { public string Name { get; set; } public string LastName { get; set; } public int Age { get; set; } } 
+2
source

In the case of dynamic user selection, I believe that a more elegant solution, rather than using if blocks, would be to declare a variable

 Func<People, bool> expFilter; 

set its value based on user selection

 switch(comboBoxOperator.Text) { case "=": expFilter = p => p.Age == age; break; case ">": expFilter = p => p.Age > age; break; case "<": expFilter = p => p.Age < age; break; } 

and then pass it to the Where clause:

 result = lPeople.Where(expFilter); 
+1
source

All Articles