¿Cómo puedo construir un árbol de expresiones cuando partes de la expresión se pasan como argumentos?Combinación de expresiones en un árbol de expresiones
E.g. ¿y si yo quería crear árboles de expresión como éstas:
IQueryable<LxUser> test1(IQueryable<LxUser> query, string foo, string bar)
{
query=query.Where(x => x.Foo.StartsWith(foo));
return query.Where(x => x.Bar.StartsWith(bar));
}
sino creando indirectamente:
IQueryable<LxUser> test2(IQueryable<LxUser> query, string foo, string bar)
{
query=testAdd(query, x => x.Foo, foo);
return testAdd(query, x => x.Bar, bar);
}
IQueryable<T> testAdd<T>(IQueryable<T> query,
Expression<Func<T, string>> select, string find)
{
// how can I combine the select expression with StartsWith?
return query.Where(x => select(x) .. y => y.StartsWith(find));
}
Resultado:
Mientras que las muestras no tenía mucho sentido (lo siento pero estaba tratando de mantenerlo simple), aquí está el resultado (gracias Quartermeister).
Se puede usar con Linq-to-Sql para buscar una cadena que comience con o sea igual a findText.
public static IQueryable<T> WhereLikeOrExact<T>(IQueryable<T> query,
Expression<Func<T, string>> selectField, string findText)
{
Expression<Func<string, bool>> find;
if (string.IsNullOrEmpty(findText) || findText=="*") return query;
if (findText.EndsWith("*"))
find=x => x.StartsWith(findText.Substring(0, findText.Length-1));
else
find=x => x==findText;
var p=Expression.Parameter(typeof(T), null);
var xpr=Expression.Invoke(find, Expression.Invoke(selectField, p));
return query.Where(Expression.Lambda<Func<T, bool>>(xpr, p));
}
e.g.
var query=context.User;
query=WhereLikeOrExact(query, x => x.FirstName, find.FirstName);
query=WhereLikeOrExact(query, x => x.LastName, find.LastName);
¡Gracias, su primera respuesta fue exactamente lo que estaba buscando! – laktak
Una nota importante aquí es que funcionará con LINQ2SQL y LINQ2Entities, pero no con EF-EF, por razones que son conocidas por sí mismas, no implementa 'Expression.Invoke'. – nicodemus13