Question

In another posting: Does Linq-To-Sql support composable queries there was discussion on how to compose/concat where clauses dynamically. This appears to be done with an "AND" (i.e. the first where clause and the second where clause are joined by an AND). What I am wondering is if there is a way to compose Linq queries with an OR.

Example:

var people = from p in Person
             where p.age < 18
             select p

var otherPeople = from p in people
                  where p.firstName equals "Daniel"
                  select p

This gives people with a first name of "Daniel" and that are under 18. I'm looking for the syntax to join these to find people who have a first name of "Daniel" or are under 18.

Note: I am using ADO.net Data Services so I do not have .Contains() available to me.

EDIT: The Union Suggestion (by Garry Shutler) is exactly what I am looking for functionality-wise. I did run into two possible issues with it:

  1. It looks like it would make multiple database hits if I was to do a third condition (union seems to take an IEnumerable as its parameter) - I was hoping to build up multiple AND and OR statements in code and then execute one request.
  2. Union is not supported by ADO.Net Data Services (very disappointing)
Was it helpful?

Solution

Is what you want as simple as:

var people = from p in Person
             where p.age < 18 || p.firstName == "Daniel"
             select p;

or have you just given a simple example?

In which case you can use:

var under18 = from p in Person
              where p.age < 18
              select p;

var daniels = from p in Person
              where p.firstName == "Daniel"
              select p;

var combined = under18.Union(daniels);

LinqToSql may be intelligent enough to convert that to an OR but I'm not so sure.

OTHER TIPS

What about using PredicateBuilder by Joe Albahari?

var predicate = PredicateBuilder.False<Person>();
predicate = predicate.Or(p => p.age < 18);
predicate = predicate.Or(p => p.firstName == "Daniel");

var query = Person.Where(predicate);

The predicate option is the way to go. The Union option DOES NOT build good sql. Reference http://social.msdn.microsoft.com/forums/en-US/linqprojectgeneral/thread/925b245d-5529-4a64-8cd4-4bc83ee6fe7a/

I wrote about how to achieve queries which search for a key value within a set on my blog . Here are the relevant links.

Contains Operations in ADO.NET Data Services Part I

Contains Operations in ADO.NET Data Services Part II

Using this , you can write queries which look like this
//The set in which we have to search for a match
List<string> citiesIWillVisit = new List<string>() {"London","Berlin","Prague"};
var customersAround = nwContext.Customers
.IsIn<Customers>(citiesIWillVisit, c=> c.City);
foreach (Customers localCustomer in customersAround) {
System.Console.WriteLine(localCustomer.ContactName);
}

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top