C# Lambda表达式与搜索

C# Lambda表达式与搜索,c#,linq,search,lambda,C#,Linq,Search,Lambda,假设我有一个表单,它包含以下内容: 名称:文本框 电子邮件:文本框 年龄:文本框 现在,我想基于此过滤器文本框获取客户集合 因此,我想使用如下内容: List<customer> customers = getCustomerswhere(c=>c.name == txtName.Text && Email == txtEmail.Text); 我该怎么做!我不能连接lambda表达式,我知道我可以使用动态表达式,但我认为有更简单的方法吗?你知道如何实现这一点

假设我有一个表单,它包含以下内容:

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

现在,我想基于此过滤器文本框获取客户集合

因此,我想使用如下内容:

List<customer> customers = getCustomerswhere(c=>c.name == txtName.Text && 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);
Func a=(bb)=>bb.fullName==“asdfsd”;
Func b=c=>c.lastName==“sdas”;
Func cc=c=>a(c)和b(c);
现在又来了一个问题

我传递CC给的方法需要
Expression


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

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

var a = c => c.name == txtName.Text;
var b = c => c.name == txtName.Text;
然后像这样连接它们:

var result = c => a(c) && b(c);
像这样:

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);
}
将导致堆栈溢出,因为
谓词
变量将始终引用您分配给它的最新不可变委托实例

return Customers.Where(c => (txtName.Text.Trim() == "" || c.Name == txtName.Text)
                      && (txtEmail.Text.Trim() == "" || c.Email == txtEmail.Text));
换句话说,如果填写了“姓名”框,则仅施加“姓名”条件;如果填写了“电子邮件”框,则仅施加“电子邮件”条件


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

以下是我如何实现它的:

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

    }
}
最后一句话:

var finalexp = criteries.GetFinalLambdaExpression();

是的,但问题是我将失去IntelisSense,我尝试了var a=(客户C)=>C.name==txtName.Text;但它给了我编译时错误:无法将lambda表达式指定给隐式类型的本地variable@Zeus这不是lambda表达式的错误,只是一个要求,即指定您希望创建的委托的类型,在您的情况下,您可以编写谓词或Func。不,不要松开安全带。唯一的松散对象是动态的。为什么会导致堆栈溢出?委托是不可变的,所以我希望RHS上的谓词引用的对象与分配给LHS@Rune:lambda将通过引用来绘制变量。调用
谓词(c)
时,
谓词
变量将引用变量中的当前不可变委托实例,即调用lambda表达式。请取消你的否决票。
   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();