Lambda表达式和搜索

时间:2010-08-10 08:37:18

标签: c# linq search lambda

假设我的表格中包含以下内容:

  

名称:文本框
  电子邮件:文本框
  年龄:TextBox中

现在我想根据此过滤器文本框获取客户收藏

所以我想使用类似的东西:

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

现在当然我不知道他会填补哪些,他不会这样做

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

我该怎么做!我不能连接lambda表达式,我知道我可以使用动态表达式,但我认为有更简单的方法吗?任何想法如何实现这个?


好的我试过这个:

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

现在又出现了另一个问题

我通过CC的方法是期待Expression<Func<T, bool>> expression

所以它不起作用给我编译时错误不能在类型之间转换!

4 个答案:

答案 0 :(得分:2)

你可以创建一些表达式,如:

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

然后将它们连接起来:

var result = c => a(c) && b(c);

答案 1 :(得分:2)

像这样:

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

Concatenate方法必须是一个单独的方法,因为lambda表达式通过引用捕获变量。

该行

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

将导致堆栈溢出,因为predicate变量将始终引用您分配给它的最新的不可变委托实例。

答案 2 :(得分:2)

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

换句话说,如果填写了“姓名”框,则仅强制执行“姓名”条件,并且只有填写“电子邮件”框才会强加“电子邮件”条件。

请注意,您可以使用.NET 4.0中的String.IsNullOrWhiteSpace方法而不是您使用的Trim技术。

答案 3 :(得分:1)

以下是我实施它的方式:

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

    }
}

并使用它:

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

和最终表达:

var finalexp = criteries.GetFinalLambdaExpression();