Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

336
Views
¿Cómo uso una matriz de valores en un generador de expresiones LINQ?

Quiero crear dinámicamente una consulta LINQ para poder hacer algo como

 var list = n.Elements().Where(getQuery("a", "b"));

en lugar de

 var list = n.Elements().Where(e => e.Name = new "a" || e.Name == "c");

(La mayoría de las veces, necesito pasar XNames con espacios de nombres, no solo nombres locales...)

Mi problema es acceder a los elementos de la matriz:

 private static Func<XElement, bool> getQuery(XName[] names) { var param = Expression.Parameter(typeof(XElement), "e"); Expression exp = Expression.Constant(false); for (int i = 0; i < names.Length; i++) { Expression eq = Expression.Equal( Expression.Property(param, typeof(XElement).GetProperty("Name")!.Name), /*--->*/ Expression.Variable(names[i].GetType(), "names[i]") ); } var lambda = Expression.Lambda<Func<XElement, bool>>(exp, param); return lambda.Compile(); }

Obviamente, la expresión Variable es incorrecta, pero tengo dificultades para crear una expresión capaz de acceder a los valores de la matriz.

over 4 years ago · Santiago Trujillo
2 answers
Answer question

0

¿Necesita crear una expresión y compilarla? A menos que me falte algún matiz en esto, todo lo que necesita es una función que devuelva un Func<XElement, bool> .

 private Func<XElement, bool> GetQuery(params string[] names) { return element => names.Any(n => element.Name == n); }

Esto toma una matriz de cadenas y devuelve Func<XElement> . Esa función devuelve verdadero si el nombre del elemento coincide con cualquiera de los argumentos.

Luego puede usar eso como lo describió:

 var list = n.Elements.Where(GetQuery("a", "b"));

Hay muchas maneras de hacer algo como esto. Para una mayor legibilidad, una extensión como esta podría ser mejor:

 public static class XElementExtensions { public static IEnumerable<XElement> WhereNamesMatch( this IEnumerable<XElement> elements, params string[] names) { return elements.Where(element => names.Any(n => element.Name == n)); } }

Entonces el código que lo usa se convierte en

 var list = n.Elements.WhereNamesMatch("a", "b");

Eso es especialmente útil cuando tenemos otros filtros en nuestra consulta LINQ. All the Where y otros métodos pueden volverse difíciles de leer. Pero si los aislamos en sus propias funciones con nombres claros, entonces el uso es más fácil de leer y podemos reutilizar la extensión en diferentes consultas.

over 4 years ago · Santiago Trujillo Report

0

Si desea escribirlo como Expresión, puede hacerlo así:

 public static Expression<Func<Person, bool>> GetQuery(Person[] names) { var parameter = Expression.Parameter(typeof(Person), "e"); var propertyInfo = typeof(Person).GetProperty("Name"); var expression = names.Aggregate( (Expression)Expression.Constant(false), (acc, next) => Expression.MakeBinary( ExpressionType.Or, acc, Expression.Equal( Expression.Constant(propertyInfo.GetValue(next)), Expression.Property(parameter, propertyInfo)))); return Expression.Lambda<Func<Person, bool>>(expression, parameter); }

Si compila o no la expresión está determinado por los medios que desea lograr. Si desea pasar la expresión a un proveedor de consultas (cf. Queryable . Where ) y hacer que, por ejemplo, la base de datos filtre sus valores, entonces no puede compilar la expresión.

Si desea filtrar una colección en la memoria, es decir, enumera todos los elementos (cf. Enumerable . Where ) y aplica el predicado a todos los elementos, entonces debe compilar la expresión. En este caso, probablemente no debería usar la API de expresión, ya que agrega complejidad a su código y, por lo tanto, es más vulnerable a los errores de tiempo de ejecución.

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!