1

I have a method which accepts a linq query:

 public IEnumerable<User> GetAll(System.Linq.Expressions.Expression<Func<UserDTO, bool>> query)
 {
     return GetAllDTO(query);
 }

What I would like to be able to do is append an additional WHERE clause to this existing query so it looks something like this:

 public IEnumerable<User> GetAll(System.Linq.Expressions.Expression<Func<UserDTO, bool>> query)
 {
    return GetAllDTO(query).Where(x => x.Organisation == "something")
 }

But this will load ALL the records and that match the query and THEN apply the where clause. I want to add the where clause to the original query so that only the records matching both are returned.

Simon
  • 6,062
  • 13
  • 60
  • 97

2 Answers2

1

This example modifies the query before executing it:

private IEnumerable<int> GetAll(Expression<Func<int, bool>> currentQuery)
{
     Expression left = currentQuery.Body;
     BinaryExpression right = Expression.GreaterThan(
         currentQuery.Parameters[0], Expression.Constant(0));
     BinaryExpression combined = Expression.AndAlso(left, right);
     Expression<Func<int, bool>> final = Expression.Lambda<Func<int, bool>>(
         combined, currentQuery.Parameters[0]);
     return GetAllInt(final);
}

If currentQuery starts as x => x != 5, the function above will return x => (x != 5) && (x > 0).

Here's the remaining example code:

private static readonly List<int> TheList = 
    new List<int> { 0, 1, 0, 2, 0, 3, 0, 4, 0, 5 };

public static void Main(string[] args)
{
    Expression<Func<int, bool>> initialQuery = x => x != 5;
    IEnumerable<int> result = GetAll(initialQuery);
    foreach (int i in result)
    {
        Console.WriteLine(i);
    }

    Console.ReadLine();
}

And the GetAllInt method:

private static IEnumerable<int> GetAllInt(Expression<Func<int, bool>> query)
{
    return TheList.Where(query.Compile());
}

This prints out:

1
2
3
4

This may not fit your situation exactly but should at least give you a starting point.

Mike Cowan
  • 919
  • 5
  • 11
1

In the end I managed it like this:

public IEnumerable<User> GetAll(System.Linq.Expressions.Expression<Func<UserDTO, bool>> query)
{
  var prefix = query.Compile();
  query = c => prefix(c) && c.Organisation == organisationID;
}
Simon
  • 6,062
  • 13
  • 60
  • 97