2013-03-19 57 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