2012-06-14 9 views
5

me encontré con la siguiente pregunta que puede combinar múltiples expresiones Expression<Func<T,bool>>:Combinar Expresión OrdenarPor con los que la expresión

How to merge two C# Lambda Expressions without an invoke?

Me pregunto si, utilizando una técnica similar, cómo usted va sobre la fusión de un .OrderBy Expression<Func<Entity, Key>> con.. Donde Expression<Func<Entity, bool>> en una expresión de tipo, o heredar de tipo, System.Linq.Expressions.Expression.

Estoy haciendo una clase de estilo QueryProvider realmente cortada para tomar T => T == ... Func's a través de los métodos públicos .Where y .OrderBy. Esto es con la intención de que la expresión que esta clase construye pasa a un QueryTranslator para crear SQL adecuado.

Un QueryTranslator de este estilo, cuando se llama desde un QueryProvider, generalmente toma un System.Linq.Expressions.Expression como un argumento que luego traduce a SQL.

Puedo seguir y entender la pregunta anterior para unir dos .Where Funcs. La siguiente entrada en el blog fue particularmente útil para esto, y rastreada a través de cada uno de los ejemplos:

http://blogs.msdn.com/b/meek/archive/2008/05/02/linq-to-entities-combining-predicates.aspx

Este artículo CodeProject también fue útil:

http://www.codeproject.com/Articles/24255/Exploring-Lambda-Expression-in-C

Cuando la combinación de un .OrderBy Func con un. Donde Func sin embargo, los dos tienen diferentes argumentos genéricos. En el caso del. Donde es un Func<Entity, bool>, y en el caso del .OrderBy es un Func<Entity, Key>.

La fusión de estas dos expresiones, en la superficie, no es tan sencilla como fusionar dos con los mismos argumentos genéricos.

El built-func-Expression-producing-engine (inseguro del término exacto) es capaz de combinar un .Where Func con un .OrderBy Func. Tengo curiosidad sobre lo que ocurre bajo el capó cuando estas dos expresiones se combinan para convertirse en una System.Linq.Expressions.Expression. ¿Es posible? En caso afirmativo, ¿cómo combinaría un Expression<Func<Entity, bool>> con un Expression<Func<Entity,Key>> asumiendo que la Entidad es del mismo tipo en cada Expresión?

+0

¿Cómo debería ser la expresión resultante? – dtb

+0

Debe ser el mismo que .Where (T => T.Name == "Cooper"). OrderBy (T => T.DateOfBirth) – Anthony

+1

Se fusiona '.Where (x => condition1) .Where (x = > condition2) 'to' .Where (x => condition1 && condition) 'pero no puede fusionar' .Where (x => condition) .OrderBy (x => value) 'en el mismo sentido. Entonces, de nuevo, ¿cómo debería ser la expresión resultante? 'queryable.Where (x => condición) .OrderBy (x => value)' no devuelve una expresión, devuelve un 'IQueryable '. – dtb

Respuesta

3
public IQueryable<T> ApplyExpressions<T, TKey>(
    Expression<Func<T, TKey>> sortBy, 
    Expression<Func<T, bool>> filterBy, 
    IQueryable<T> source) 
{ 
    return source.Where(filterBy).OrderBy(sortBy); 
} 


IQueryable<Customer> query = ApplyExpressions<Customer, int>(
    c => c.Age, 
    c => c.Name.StartsWith("B"), 
    myDC.Customers) 

Expression queryExpression = query.Expression; //tada 
+0

Me gusta la franqueza, pero no es lo que busco. No tengo una fuente disponible, así que no hay nada contra lo que preguntar de esta manera. – Anthony

0

Creo que esta pregunta se volvió ambigua porque no se puede responder.

Estaba tratando de construir una superexpresión, como la forma en que el generador de expresiones IQueryable<> funciona con las expresiones .Where y .OrderBy todo en una expresión.

Sin un asunto, sin embargo, mi comprensión limitada de Expressions y Expression Trees parece sugerir que no es posible.

Para combinar una expresión .Where con una expresión .OrderBy en una expresión que necesita MethodCallExpression 's para separar los dos LambdaExpression s.

El MethodCallExpression necesita un sujeto para llamar al método. Aquí es donde se usa el IQueryable<>.

He alterado mi clase de Consulta para mantener todas las LambdaExpression separadas, y estas se pasan al QueryTranslator por separado. El QT fusiona el SQL de salida en los lugares correctos.

Esto es opuesto a IQueryable<> QueryProvider que analiza una superexpresión y emite SQL en los lugares correctos basándose en MethodCallExpression en Expression.

Cuestiones relacionadas