2010-03-21 78 views
7

我想知道如何能够使一个表达式树通过输入一个以上的参数多个条件

例子:

dataContext.Users.Where(u => u.username == "Username" && u.password == "Password") 

目前的代码,我所做的就是以下,但想做出更一般的问候条件是否为OR或AND

public Func<TLinqEntity, bool> ANDOnlyParams(string[] paramNames, object[] values) 
    { 
     List<ParameterExpression> paramList = new List<ParameterExpression>(); 
     foreach (string param in paramNames) 
     { 
      paramList.Add(Expression.Parameter(typeof(TLinqEntity), param)); 
     } 

     List<LambdaExpression> lexList = new List<LambdaExpression>(); 
     for (int i = 0; i < paramNames.Length; i++) 
     { 
      if (i == 0) 
      { 
       Expression bodyInner = Expression.Equal(
            Expression.Property(
             paramList[i], paramNames[i]), 
             Expression.Constant(values[i])); 
       lexList.Add(Expression.Lambda(bodyInner, paramList[i])); 
      } 
      else 
      { 
       Expression bodyOuter = Expression.And(
            Expression.Equal(
            Expression.Property(
            paramList[i], paramNames[i]), 
            Expression.Constant(values[i])), 
            Expression.Invoke(lexList[i - 1], paramList[i])); 
       lexList.Add(Expression.Lambda(bodyOuter, paramList[i])); 
      } 
     } 

     return ((Expression<Func<TLinqEntity, bool>>)lexList[lexList.Count - 1]).Compile(); 
    } 

感谢

回答

2

Expression.And在这里使用是错误的,它是按位和。你想要AndAlso

除了你已经知道如何构建表达式树的机制之外,它似乎就像你。所以你真正要问的是,如何让建筑方法的调用者指定一种更复杂,更灵活的方式来组合不同的条件。

最终,为了获得真正的灵活性,您需要一个迷你查询语言。解析语言以构建表达式树。

在短期内,你可能会与一些更简单的获取方式:原始表达式的列表和一个布尔标志说是否他们应该& &或||结合。

更新 - 我注意到你实际上是在将一个结果表达式编译成一个真正的委托。这让我很想知道为什么你这样做是艰难的。为什么不把表达式写成lambda表达式,就像你最初的例子那样? (如果您使用Linq to SQL或EF,则不应编译表达式。)

更新2 - 您可能需要的是Dynamic Linq

+0

关于为什么我要用艰难的方式(返回委托),原因是在设计时没有直接访问数据库列名称。我无法访问使用datacontext.table.Where(...);因为我已经在数据库中加密了表名。 感谢您的回答我会寻找AndAlso方法... – Ryan 2010-03-21 12:38:40

+0

@Ryan - 见更新 - 我记得这样做的图书馆! – 2010-03-21 12:48:25

+0

谢谢丹尼尔......我真的很感激它看起来像我需要:) – Ryan 2010-03-21 13:15:03