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

346
Views
How do I use an array of values in a LINQ Expression builder?

I want to dynamically build a LINQ query so I can do something like

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

instead of

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

(Most of the time, I need to pass XNames with namespaces, not just localnames...)

My problem is in accessing the array elements:

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();
}

Obviously the Variable expression is wrong, but I'm having difficulty building an expression capable of accessing the array values.

over 4 years ago · Santiago Trujillo
2 answers
Answer question

0

Do you need to create an expression and compile it? Unless I'm missing some nuance to this, all you need is a function that returns a Func<XElement, bool>.

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

This takes an array of strings and returns a Func<XElement>. That function returns true if the element name matches any of the arguments.

You can then use that as you described:

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

There are plenty of ways to do something like this. For increased readability an extension like this might be better:

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));
    }
}

Then the code that uses it becomes

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

That's especially helpful when we have other filters in our LINQ query. All the Where and other methods can become hard to read. But if we isolate them into their own functions with clear names then the usage is easier to read, and we can re-use the extension in different queries.

over 4 years ago · Santiago Trujillo Report

0

If you want to write it as Expression you can do it like so:

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);
}

Whether or not you compile the expression is determined by the means you want to achieve. If you want to pass the expression to a query provider (cf. Queryable.Where) and have e.g. the database filter your values, then you may not compile the expression.

If you want to filter a collection in memory, i.e. you enumerate all elements (cf. Enumerable.Where) and apply the predicate to all the elements, then you have to compile the expression. In this case you should probably not use the Expression api as this adds complexity to your code and you are then more vulnerable to runtime errors.

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!