2010-03-21 16 views
7

Me gustaría saber cómo ser capaz de hacer un árbol de expresión mediante la introducción de más de un parámetrovarias condiciones en lambda expresiones en tiempo de ejecución C#

Ejemplo:

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

En el momento en que el código que yo era la siguiente, pero le gustaría hacer más general en cuanto a si la condición es OR o 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(); 
    } 

Gracias

Respuesta

2

Expression.And es incorrecto utilizar aquí, es el bitwise y. Quiere AndAlso.

Parece que, aparte de eso, ya conoce la mecánica de cómo construir el árbol de expresiones. Entonces, lo que realmente está preguntando es cómo puede permitir que la persona que llama de su método de construcción especifique una forma más complicada y flexible de combinar diferentes condiciones.

En definitiva, para una verdadera flexibilidad necesita un lenguaje de consulta mínima. Analiza el lenguaje para construir el árbol de expresiones.

En el corto plazo, puede pasar con algo mucho más simple: una lista de expresiones primitivas y una bandera bool para decir si se deben combinar con & & o ||.

Actualización - Me doy cuenta de que en realidad está compilando la expresión resultante en un delegado real. Esto me hace preguntarme por qué estás haciendo esto de la manera difícil en primer lugar. ¿Por qué no solo escribes la expresión como lambda, como en tu ejemplo inicial? (Si está utilizando LINQ a SQL o EF, no debe ser la compilación de la expresión de todos modos.)

Actualización 2 - Lo que probablemente necesita es Dynamic Linq.

+0

En cuanto a por qué estoy yendo por el camino difícil (devolver un delegado), la razón es que no tienen acceso directo a los nombres de las columnas de la base de datos en tiempo de diseño. Y no puedo acceder usando datacontext.table.Where (...); porque tengo los nombres de las tablas encriptados dentro de la base de datos. Gracias por su respuesta, buscaré el método AndAlso ... – Ryan

+0

@Ryan - ver actualización - ¡Recordé la biblioteca que hace esto! –

+0

Gracias Daniel ... Realmente aprecio que parece exactamente lo que necesito :) – Ryan