Introduction to Language Integrated Query (LINQ)
The focus of this article will be an introduction to Language Integrated Query, or LINQ for short. This article will cover what LINQ is and isn't, with a brief refresher on the language features that enable it, and then jump in to some examples of working with LINQ. This will be part one of a couple of articles that cover LINQ in some detail.
What is Language INtegrated Query?
Many of my past articles, even all the way back to some of my first articles such as Database Independent Data Access, have had something to do with accessing and manipulating data. Commonly, data is stored in a database, but there are many other forms of accessing and manipulating data as well such as data files, event logs, the Registry, and so forth. Querying and manipulating data is a common part of many applications.
LINQ (often overheard pronounced as "link") is a step in the evolution of data access. It is a programming model that brings a much needed uniformity to accessing data from files, XML, database, registry, event log, and a whole host of other sources of data such as Active Directory and even services from 3rd parties such as Flickr. It is designed to work with all shapes and sizes of different data and allow you to perform Query, Set, and Transform operations on all of it. Pretty much anything that implements IEnumerable is a target for LINQ.
What Is LINQ Not?
It can be just as useful when trying to understand something to look at the counter of what it is, which is what it is not. One of the most common reactions I've heard about when people are first introduced to LINQ is that it is just embedded SQL, which it is not. Although LINQ syntax can be SQL-like in many of its forms, it is not just embedded SQL and is not limited to just querying databases. LINQ is not automatically supported by all .NET languages. There were no modifications to the Common Language Runtime (CLR). All of the modifications were made to the languages and their respective compilers. It requires some language-specific extensions. Visual Basic .NET 9.0 and C# 3.0 both have integrated language support for LINQ.
Language Features that Enable LINQ
LINQ makes heavy use of Generics. Additionally, there were a number of features added to the Visual Basic and C# languages specifically to support LINQ. A couple of my more recent articles introduced some of these language features as a precursor to LINQ. The following contains a partial list of the language features that help enable LINQ and a brief description of each:
- Type inference: Shorthand indicating the variables type is the compile time type of the right hand assignment
- Extension Methods: Extending an existing value or reference type without deriving a new type
- Object initializer: Short form of object initialization syntax that generates the equivalent code
- Anonymous types: Create statements without constructing a method or type
- Lambda expressions: Concise way of creating inline methods
- Query expressions: SQL-like statements within code for manipulating objects
I'm certain each of these languages features adds some benefit on their own, but I've not personally found reason yet to use many of them outside of LINQ.
Flavors of LINQ
There are a variety of flavors of LINQ for accessing and manipulating different data sources. The trailing list contains some of the data domains provided by Microsoft. Some of these will be topics of future .NET Nuts and Bolts articles.
- LINQ to Objects: Manipulates collections of objects
- LINQ to DataSets: Manipulates a DataSet using LINQ
- LINQ to SQL: Maps between custom types and a physical database table schema
- LINQ to Entities: Uses a conceptual Entity Data Model to create a conceptual model of a physical database
- LINQ to XML: Allows querying and manipulation of XML
Introduction to LINQ Syntax
For those who are very particular about how their code is structured and formatted, it is likely to take a little bit to get comfortable with LINQ syntax and having it sit in your code. For those whi have routinely heard the mantra not to embed SQL queries within your code, it will take a bit to get comfortable that you are not indeed doing anything wrong or dirty by using LINQ, but rather quite the opposite.
Even though LINQ absolutely is not limited just to accessing databases, I have found it of value in helping people to understand LINQ to first examine a SQL statement and then introducing the in-code LINQ representation of the same thing. The following SQL statement is one constructed against the Northwind sample database common to Microsoft SQL Server. The query is pretty basic and simply pulls a list of customers that are not located in the city of Berlin.
SELECT c.CompanyName, c.ContactName, c.CityFROM Customers cWHERE c.City != 'Berlin'ORDER BY c.ContactName
Now, look at a LINQ representation of the same thing and dissect it to understand the pieces and parts. There are two different types of query syntaxes: query expressions and method queries. You'll focus on query expressions for now. The following query expression would search the IEnumerable type returned from GetCustomers() and find those that did not have a City location of Berlin. For this example, you'll assume the GetCustomers method accesses the database and returns an IEnumerable type.
var customerNotInBerlin = from c in GetCustomers() where c.City != "Berlin" orderby c.ContactName select c;
The following table outlines some of the options available with LINQ syntax.
|Destination||var <variable> =||Using type inference to assign the resulting value(s)|
|Source||from <item> in <data source>||Information source providing a set of item(s)|
|Filter||where <expression>, distinct||Expression specifying the selection criteria|
|Order||order by <expression>, <expression> [Ascending | Descending]||Control the ordering of the results|
|Aggregate||count([<expression>]), sum(<expression>), min(<expression>), max(<expression>), avg(<expression>)||Aggregate the source items|
|Projection||select <expression>||Shaping the output|
There are many more options and variations of syntax than what is provided above, but this should give you a starting point for familiarity.
Page 1 of 3