C# 动态构建 lambda 表达式
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/904296/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Dynamic build lambda expressions
提问by Henrik P. Hessel
So, I started to build a small test application to test lambda expressions. I found several examples here and elsewhere but I just don't get them.
因此,我开始构建一个小型测试应用程序来测试 lambda 表达式。我在这里和其他地方找到了几个例子,但我就是不明白。
Can anybody explain my how to build an expression by using textboxes 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
工作 lambda 表达式
IEnumerable<People> result = lPeople.Where(p => p.Age < 21);
dgv_1.DataSource = result.ToList();
dgv_1.Update();
How can I build the expressions dynamically?
如何动态构建表达式?
Something like lPeople.Where(p => p.LastName == Textbox.Text);
(which of course doesn't work)
类似的东西lPeople.Where(p => p.LastName == Textbox.Text);
(这当然不起作用)
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;
}
采纳答案by Daniel Earwicker
"which of course doesn't work"
“这当然行不通”
What happens when you try it? By the look of it, that's the kind of thing I do all the time.
当你尝试时会发生什么?看样子,这就是我一直在做的事情。
To switch operations based on a ComboBox specifying the operator:
要根据指定运算符的 ComboBox 切换操作:
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();
The code that converts the age string into an int
will throw if the user enters something that can't be converted. Look up TryParse
to avoid exceptions.
int
如果用户输入了无法转换的内容,则将年龄字符串转换为 an 的代码将抛出。查找TryParse
以避免异常。
回答by Robert Harvey
You can use the Linq Dynamic Query Library to accomplish this. See the following blog post from Scott Guthrie for more information:
您可以使用 Linq 动态查询库来完成此操作。有关更多信息,请参阅 Scott Guthrie 的以下博客文章:
回答by Sudhir Jonathan
Try the Predicate Builder at http://www.albahari.com/nutshell/predicatebuilder.aspx
在http://www.albahari.com/nutshell/predicatebuilder.aspx试试 Predicate Builder
I used it to make an advanced search where the user could keep adding optional search criteria.
我用它来进行高级搜索,用户可以在其中不断添加可选的搜索条件。
回答by Jason
Your example lambda expression will work. How dynamic do you need it to be? If you have a static UI of 'filters' to apply to a collection, you can create code similar to the following:
您的示例 lambda 表达式将起作用。你需要它有多动态?如果您有一个“过滤器”的静态 UI 应用于集合,您可以创建类似于以下内容的代码:
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 apply truly dynamic expressions (afford them the ability to choose other fields to filter and the expressions to use), that's a more complicated feature to implement using a predicate builder tool or LINQ Expression objects.
如果您希望数据源的使用者应用真正的动态表达式(让他们能够选择要过滤的其他字段和要使用的表达式),那么使用谓词构建器工具或 LINQ 表达式对象来实现这是一个更复杂的功能。
回答by John Rasch
There should be nothing wrong with the way you're going about it. I have created a simple Windows Forms Application with a TextBox
, a Button
, and a DataGridView
(with names textBox1
, button1
, and dgv_1
respectively.)
你这样做的方式应该没有问题。我创建了一个简单的Windows窗体应用程序TextBox
,一Button
,和DataGridView
(同名称textBox1
,button1
和dgv_1
分别。)
Here is the code I used for the Form1.cs
file that worked as expected:
这是我用于Form1.cs
按预期工作的文件的代码:
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; }
}
回答by g1ga
In case of dynamic user choice, I think that a more elegant solution rather then using if blocks would be to declare a variable
在动态用户选择的情况下,我认为比使用 if 块更优雅的解决方案是声明一个变量
Func<People, bool> expFilter;
set its value based upon the user choice
根据用户选择设置其值
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:
然后将其传递给 Where 子句:
result = lPeople.Where(expFilter);