Language Integrated Query, or LINQ, is a flexible, SQL-like query language designed to give the programmer consistent syntax to query any data set, whether database, XML, or just plain objects. What’s more, it’s usable from the comfort and safety of your everyday C# file.
LINQ is a language that merely looks like SQL, and only superficially. If you’re familiar with SQL, you’ll notice that the various parts of the query appear in a different order than you’re used to. LINQ is not directly related to actual database SQL languages and is not a way of embedding actual SQL queries in your code. It is a way of embedding generic queries in your code that may eventually turn into database queries, but LINQ can do so much more.
Solution: This and the following examples use some data objects to demonstrate how LINQ works.
The most basic LINQ query just retrieves all the book information.
The var
keyword is often used with LINQ for reasons you’ll see later. In this case, allBooks
is a collection of Book
objects. The output is as follows:
Solution: Use the orderby
statement.
Here’s how to order the results in ascending order (the default):
var ordered = from book in books orderby book.Title select book;
Use the following for descending order:
And here’s how to sort multiple columns:
Solution: Like SQL, LINQ has a where
clause which can be used to filter the results according to the conditions you specify:
Here’s the output:
If you want to use multiple conditions, use the &&
and ||
operators just as you would in an if
statement:
Solution: Before LINQ, this involved some usually trivial but clunky code to iterate over all the objects and insert the desired properties into a new collection. With LINQ, it’s a single line (which is broken here due to the limited width of the page:
This line returns titles of books published after 1850:
The result, justTitlesAfter1850
, is a collection of string objects, but what if you want to project out more than one field? See the next section.
Solution: Use the join
keyword to combine tables on a common field.
This is where the true power of LINQ shines through. In this example, the Author
collection will be combined with the Book
collection, and only the author and title information will be projected out.
So what is the type of withAuthors
? It is an anonymous type (see Chapter 1, “Type Fundamentals”) generated for the purpose of just this LINQ query. Because there is no type name for it (at least, not in the code there isn’t), var
must be used to refer to both the collection and the collection’s objects.
LINQ can generates these anonymous objects as needed, but it can also set properties in an existing named object that you specify. See the LINQ to Bing example later in this chapter.
Solution: LINQ contains its own set of XML-manipulation classes that are optimized for LINQ queries. The syntax of the query itself is exactly the same as with plain objects:
This example uses the same LesMis.xml file from Chapter 14’s XPath
discussion. The output is as follows:
Solution: Although LINQ can of course load and query XML generated from any source, it also provides very easy XML-creation mechanisms.
The preceding creates the following XML fragment:
Solution: Although there is such a thing as LINQ to SQL, LINQ only works with SQL Server, and it has been more or less deprecated by Microsoft. The recommendation is to use LINQ to Entity Framework, so that is what will be discussed here.
Figure 21.1 shows the Entity Framework diagram of an Author and Book table, in addition to a Textbook table that is used later in this section.
The LINQ code in this section is very similar to that in earlier sections:
The following output is produced:
The Entity Framework allows you to specify inheritance relationships within the database tables. LINQ works seamlessly with this feature:
Solution: Out of the box, LINQ can query object collections, SQL, entities, and XML. To expand its capabilities, you have a choice: Implement a custom LINQ provider, or convert your target into one of the current implementations.
The latter option is generally much easier to implement and is shown in Listings 21.1 and 21.2. The Bing API is used to demonstrate using LINQ to convert the XML results to custom objects.
To see an excellent example of how to create a custom LINQ provider (and gain an appreciation for how much work goes into creating a good one), see Fabrice Marguerie’s LINQ to Amazon example at http://weblogs.asp.net/fmarguerie/archive/2006/06/26/Introducing-Linq-to-Amazon.aspx and in the book LINQ in Action.
Solution: Use the AsParallel()
extension method.
If your original query is
where ComplexCriteria()
is just an arbitrary Boolean function that examines the values in the data, then you can parallelize this with a simple addition:
You are more likely to get elements returned out of order using PLINQ unless you specify that you want order preserved using the AsOrdered()
or OrderBy()
extension method, as shown here:
Unfortunately, this might negate some of the benefits of using PLINQ.
PLINQ only works on LINQ to Objects and LINQ to XML.