You have two options here - Queryable.Union
, or expression combination. I'd generally favor the latter, via OrElse
- which (with LINQ-to-SQL at least) you can do with 2 expressions (see below) - but in either case it should get composed:
using(var ctx = new DataClasses1DataContext())
{
ctx.Log = Console.Out;
Expression<Func<Customer, bool>> lhs =
x => x.Country == "UK";
Expression<Func<Customer, bool>> rhs =
x => x.ContactName.StartsWith("A");
var arr1 = ctx.Customers.Where(
lhs.OrElse(rhs)).ToArray();
var arr2 = ctx.Customers.Where(lhs)
.Union(ctx.Customers.Where(rhs)).ToArray();
}
Both arr1
and arr2
each only perform 1 database hit (although the TSQL is different; the first has an OR
in the WHERE
clause; the second has two separate queries with UNION
).
Here's the extension method I used:
static Expression<Func<T, bool>> OrElse<T>(
this Expression<Func<T, bool>> lhs,
Expression<Func<T, bool>> rhs)
{
var row = Expression.Parameter(typeof(T), "row");
var body = Expression.OrElse(
Expression.Invoke(lhs, row),
Expression.Invoke(rhs, row));
return Expression.Lambda<Func<T, bool>>(body, row);
}
Marc Gravell
2009-02-20 14:25:42