2013-03-19 51 views
3

我有一个问题,如何添加另一个过滤器,并且我必须验证它是否被选中?如何创建动态的Lambda表达式

private Expression < Func < Entity.Modelos.Flux, bool >> Filter() { 
    var dateStart = dtpDateStart.Value.Date; 
    var dateEnd = dtpDateEnd.Value.Date; 

    Expression < Func < Entity.Modelos.Flux, bool >> expr = null; 

    expr = f = > f.DatFlux >= dateStart.Date && f.DatFlux <= dateEnd.Date; 

    if (txtDescription.Text != String.Empty) { 
     //add filter 
    } 

    return expr; 
} 

更新:我将在这个函数中使用表达式:

public virtual IQueryable <T> Filter(Expression < Func < T, bool >> expressao) { 
    return DbSet.Where(expressao).AsQueryable <T>(); 
} 

什么,我试图做的就是这一点,但与表达

public List <Users> GetUsers(int ? id, string name) { 
    using(DBContext ctx = new DBContext()) { 
     IQueryable query = ctx.Usuarios; 
     if (id.HasValue) 
      query = query.Where(x = > x.ID == id); 

     if (!string.IsNullOrEmpty(name)) 
      query = query.Where(x = > x.Name.StartsWith(name)); 

     return query.ToList(); 

    } 
} 
+2

请与您的编程语言标记这一点。 – 2013-03-19 17:38:14

+0

你是说你试图用你的语句传回另一个表达式,或者你试图嵌入lambda表达式?我不完全理解你正在尝试做什么 – Corylulu 2013-03-19 17:48:59

+0

我想嵌入lambda表达式。 – davidterra 2013-03-19 17:52:02

回答

0

继承ExpressionVisitor

public class MyVisitor: ExpressionVisitor 
{ 
    private LambdaExpression visitor; 
    public Expression Modify(Expression expression, LambdaExpression visitor) 
    { 
     this.visitor = visitor; 
     return Visit(expression); 
    } 

    protected override Expression VisitBinary(BinaryExpression b) 
    { 
     var binary = visitor.Body as BinaryExpression; 

     return Expression.MakeBinary(ExpressionType.AndAlso, b, binary, b.IsLiftedToNull, b.Method); 
    } 
} 

Filter()方法可能是这样

private Expression<Func<Entity.Modelos.Flux, bool>> Filter() 
    { 
     var dateStart = dtpDateStart.Value.Date; 
     var dateEnd = dtpDateEnd.Value.Date; 
     var description = txtDescription.Text; 

     Expression<Func<Entity.Modelos.Flux, bool>> expr = null; 

     expr = f => f.DatFlux >= dateStart.Date && f.DatFlux <= dateEnd.Date; 

     if (description != String.Empty) 
     { 
      //add filter 
      Expression<Func<Entity.Modelos.Flux, bool>> other = f => f.Description == description; 

      var modifier = new MyVisitor(); 
      expr = (Expression<Func<Entity.Modelos.Flux, bool>>)modifier.Modify((Expression)expr, (LambdaExpression)other); 
     } 

     return expr; 
    } 

example

看看下面的详细信息

How to: Modify Expression Trees (C# and Visual Basic)

+0

返回错误{“值不能为空。\ r \ nParameter name:right”} – davidterra 2013-03-20 01:03:59

+0

return Expression.MakeBinary(ExpressionType.AndAlso,b,binary,b.IsLiftedToNull,b.Method); – davidterra 2013-03-20 12:18:58

0

如果这是只是您的需求演示,那么您可以使用System.Linq.Expressions命名空间创建并修改Expression Trees

然而,在你的问题的情况下,它可能会更容易使用EF:

bool filterDescription = !String.IsNullOrEmpty(txtDescription.Text); 

expr = f => 
    (
    (f.DatFlux >= dateStart.Date && f.DatFlux <= dateEnd.Date) 
    && 
    (!filterDescription || ... add filter ...) 
) 
; 

或普通的C#:

if (String.IsNullOrEmpty(txtDescription.Text)) 
{ 
    expr = f => f.DatFlux >= dateStart.Date && f.DatFlux <= dateEnd.Date; 
} 
else 
{ 
    expr = f => f.DatFlux >= dateStart.Date && f.DatFlux <= dateEnd.Date 
    && 
    ... add filter ... 
    ; 
} 
0

好,嗯,这里是如何的样本嵌入lambda语句。这不是你的例子,但在这里亚去:

Func<int, int, EventHandler> makeHandler = 
    (dx, dy) => (sender, e) => { 
     var btn = (Button) sender; 
     btn.Top += dy; 
     btn.Left += dx; 
    }; 

btnUp.Click += makeHandler(0, -1); 
btnDown.Click += makeHandler(0, 1); 
btnLeft.Click += makeHandler(-1, 0); 
btnRight.Click += makeHandler(1, 0); 
0

It is simple.Visit this link

棘手的事情是调用OrderByAlias - 使用MakeGenericMethod可能的方式,如上面的链接。

+3

我不会将表达式树分类为“简单”...(另外:此答案应该可能是注释,IMO) – 2013-03-19 18:09:01

0

试试这个方法:

private Expression<Func<Entity.Modelos.Flux, bool>> Filter() 
{ 
    var dateStart = dtpDateStart.Value.Date; 
    var dateEnd = dtpDateEnd.Value.Date; 

    Func<Entity.Modelos.Flux, bool> expr = null; 

    expr = f => f.DatFlux >= dateStart.Date && f.DatFlux <= dateEnd.Date; 

    if(txtDescription.Text != String.Empty) 
    { 
     expr = f => expr(f) && f.Title.Equals(txtDescription.Text); // ← Your additional filter 
    } 

    return f => expr(f); 
} 
+0

获取错误“在LINQ to Entities中不支持LINQ表达式节点类型'Invoke'” – davidterra 2013-03-20 00:14:10