动态构建 lambda 表达式

发布于 2024-07-22 00:07:37 字数 781 浏览 6 评论 0原文

因此,我开始构建一个小型测试应用程序来测试 lambda 表达式。 我在这里和其他地方找到了几个例子,但我就是不明白。

谁能解释我如何使用文本框或任何其他变量构建表达式?

我的测试列表

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

工作 lambda 表达式

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

如何动态构建表达式?

类似于 lPeople.Where(p => p.LastName == Textbox.Text); (这当然不起作用)

谢谢!

编辑:在下面的解决方案中添加了一些代码

Int32 iAge;
Boolean bSuc = Int32.TryParse(tb_filter_age.Text, out iAge);
if (!bSuc)
{
    iAge = 0;
}

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.

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

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)

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;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

迷你仙 2024-07-29 00:07:37

“这当然行不通”

当你尝试时会发生什么? 从表面上看,这就是我一直在做的事情。

基于指定运算符的 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();

如果用户输入无法转换的内容,则将年龄字符串转换为 int 的代码将抛出异常。 查找 TryParse 以避免异常。

"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:

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.

寄意 2024-07-29 00:07:37

尝试使用谓词生成器 http://www.albahari.com/nutshell/predicatebuilder.aspx

我用它进行高级搜索,用户可以不断添加可选的搜索条件。

Try the Predicate Builder at http://www.albahari.com/nutshell/predicatebuilder.aspx

I used it to make an advanced search where the user could keep adding optional search criteria.

滿滿的愛 2024-07-29 00:07:37

您可以使用 Linq 动态查询库来完成此任务。 有关详细信息,请参阅 Scott Guthrie 的以下博客文章:

http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-动态查询库.aspx

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

贪了杯 2024-07-29 00:07:37

您的示例 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();

如果您希望数据源的使用者应用真正的动态表达式(使他们能够选择其他字段进行过滤)以及要使用的表达式),这是使用谓词构建器工具或 LINQ 表达式对象实现的更复杂的功能。

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:

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.

闻呓 2024-07-29 00:07:37

你处理这件事的方式应该没有什么问题。 我创建了一个简单的 Windows 窗体应用程序,其中包含一个 TextBox、一个 Button 和一个 DataGridView(名称为 textBox1button1dgv_1 。)

以下是我用于按预期工作的 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; }
}

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.)

Here is the code I used for the Form1.cs file that 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; }
}
流心雨 2024-07-29 00:07:37

在动态用户选择的情况下,我认为比使用 if 块更优雅的解决方案是声明一个变量,

Func<People, bool> expFilter;

根据用户选择设置其值

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

   case ">":
   expFilter = p => p.Age > age;
   break;

   case "<":
   expFilter = p => p.Age < age;
   break;
}    

,然后将其传递给Where 子句:

result = lPeople.Where(expFilter);        

In case of dynamic user choice, I think that a more elegant solution rather then using if blocks would be to declare a variable

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:

result = lPeople.Where(expFilter);        
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文