+5  A: 

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
That row thing could be anything right? (Any string that is, of course)
Svish
Thinking of sql performance and such, is it more efficient with a `UNION` or an `OR` in the `WHERE`clause?
Svish
Very nice. This question keeps coming up (in variations) and your OrElse just might be the magic bullet that solves them all.
David B
Yes, it could be "row", "x", or "Fred". Re performance: you'd need to profile it... different queries my behave differently. In *general* OR would be more efficient, but there are cases where UNION turns out to be better; and cases when two separate queries are better.
Marc Gravell
@David B - if only Entity Framework supported Expression.Invoke properly...
Marc Gravell
Nice. Expression stuff is slowly but steadily starting to make sense, hehe. Looks like it will work, although I wont get to test it out fully until Monday. Will probably stick with the OR, since that is more efficient in *general* =) Thank you, once again!
Svish