LINQ - izznogooood/dotnet-wiki GitHub Wiki

Language-Integrated Query (LINQ) is the name for a set of technologies based on the integration of query capabilities directly into the C# language. Query expressions are written in a declarative query syntax. By using query syntax, you can perform filtering, ordering, and grouping operations on data sources with a minimum of code. You use the same basic query expression patterns to query and transform data in SQL databases, ADO.NET Datasets, XML documents and streams, and .NET collections.

The sample below assumes a collection of suits (♠, ♥, ♣, ♦) and ranks (2, 3, 4, 5, 6, 7, 8, 9, 10, J, Q, K, A):

var startingDeck = from s in Suits()
                   from r in Ranks()
                   select new { Suit = s, Rank = r };

Note that the from clause is at the head of the expression as opposed to an SQL query, this allow intellisens to determine valid expressions in the following statements.

A good introduction to LINQ is the article Work with Language-Integrated Query, also see the tutorial Writing Queries in C# (LINQ) to get started!

Query parts

The from clause

A query expression must begin with a from clause. Additionally, a query expression can contain sub-queries, which also begin with a from clause. The from clause specifies the following:

  • The data source on which the query or sub-query will be run.

  • A local range variable that represents each element in the source sequence.

The type of the range variable (s and r in the sample above) is inferred by the compiler. Because the range variable is strongly typed, you can call methods on it or use it in other operations.

The where clause

The where clause is used in a query expression to specify which elements from the data source will be returned in the query expression.

The sample below selects all the lower value cards of suite spades in the deck:

var lowerSpades = from s in Suits()
                  from r in Ranks()
                  where r < 10 && s == "♠"
                  select new { Suit = s, Rank = r };

The where clause is a filtering mechanism. It can be positioned almost anywhere in a query expression, except it cannot be the first or last clause. A where clause may appear either before or after a group clause depending on whether you have to filter the source elements before or after they are grouped.

The select clause

In a query expression, the select clause specifies the type of values that will be produced when the query is executed. The result is based on the evaluation of all the previous clauses and on any expressions in the select clause itself. A query expression must terminate with either a select clause or a group clause.

Other parts

  var suitsGrouped = from s in Suits()
                     from r in Ranks()
                     let c = new { Suit = s, Rank = r }
                     group c by c.Suit into g
                     select g;

Query Execution

Deferred Execution

The actual execution of the query is deferred until you iterate over the query variable. You may therefore execute it repeatedly to retrieve different results every time.

Forcing Immediate Execution

To force immediate execution of any query and cache its results, you can call the ToList or ToArray methods. Calling ToList or ToArray caches all the data in a single collection object.

PLINQ

Parallel LINQ (PLINQ) is a parallel implementation of the Language-Integrated Query (LINQ) pattern. PLINQ implements the full set of LINQ standard query operators as extension methods for the System.Linq namespace and has additional operators for parallel operations. PLINQ combines the simplicity and readability of LINQ syntax with the power of parallel programming.

LINQ samples

For a truly comprehensive list of LINQ samples, visit 101 LINQ Samples.