Tags

, , , , , ,


LINQ

Over the past 20 years object-oriented programming languages have evolved to become the premier tools for enterprise application development. They’ve been augmented by frameworks, APIs, and rapid application-development tools. Yet what’s been missing is a way to intimately tie object-oriented programs to relational databases (and other data that doesn’t exist as objects). The object paradigm is conceptually different from the relational one and this creates significant impedance between the objects programs use and the tables where data resides. ADO.NET provides a convenient interface to relational data, but not an objectoriented one. For example, this pseudocode would be really cool:
// A class representing a table of employees
Employees e = new Employees();
// Set the row identifier to one
e.ID = 1;
// Retrieve the row where ID=1
e.Retrieve();
// Change the Name column value to Alan
e.Name = “Alan”;
// Modify the database data
e.Upate();
The pseudocode shows an object-oriented approach to data management; no query or SQL statement is visible to developers. You need to think about only what you have to do, not how to do it. This approach to combining object-oriented and relational technologies has been called the Object-Relational Mapping (ORM) model. Although Microsoft has embedded ORM capabilities in its Dynamics CRM 3.0 application server and should soon do the same in ADO.NET 3.0, it doesn’t yet provide this programming model to .NET developers. To run a simple SQL query, ADO.NET programmers have to store the SQL in a Command object, associate the Command with a Connection object and execute it on that Connection object, then use a DataReader or other object to retrieve the result set. For example, the following code is necessary to retrieve the single row accessed in the
pseudocode presented earlier.
// Specify the connection to the DB
SqlConnection c = new SqlConnection(…);
// Open the connection
c.Open();
// Specify the SQL Command
SELECT
*
FROM
Employees e
WHERE
e.ID = @p0
“);
// Add a value to the parameter
cmd.Parameters.AddWithValue(“@p0”, 1);
// Excute the command
DataReader dr = c.Execute(cmd);
// Retrieve the Name column value
while (dr.Read()) {
string name = dr.GetString(0);
}
// Update record using another Command object

// Close the connection
c.Close();
Not only is this a lot more code than the ORM code, but there’s also no way for the C# compiler to check our query against our use of the data it returns. When we retrieve the employee’s name we have to know the column’s position in the database table to find it in the result. It’s a common mistake to retrieve the wrong column and get a type exception or bad data at run time.
ADO.NET moved toward ORM with strongly typed DataSets. But we still have to write the same kind of code, using a DataAdapter instead of a Command object. The DataAdapter contains four Command objects, one for each database operation––SELECT, DELETE, INSERT, and UPDATE––and we have fill the correct one with the appropriate SQL code. .NET can also handle XML and nonrelational data sources, but then we have to know other ways to query information, such as XPath or XQuery. SQL and XML can be made to work together but only by shifting mental gears at the right time.

What Is LINQ?

At the Microsoft Professional Developers Conference (PDC) 2005, Anders Hejlsberg and his team presented a new approach, Language-Integrated Query (LINQ), that unifies the way data can be retrieved in .NET. LINQ provides a uniform way to retrieve data from any object that implements the IEnumerable<T> interface. With LINQ, arrays, collections, relational data, and XML are all potential data sources.

Why LINQ?

With LINQ, you can use the same syntax to retrieve data from any data source: var query = from e in employees select e.name
This is not pseudocode; this is LINQ syntax, and it’s very similar to SQL. The LINQ team’s goal was not to add yet another way to access data, but to provide a native, integrated set of instructions to query any kind of data source. Using C# keywords, we can write data access code as part of C#, and the C# compiler will be able to enforce type safety and even logical consistency. LINQ provides a rich set of instructions to implement complex queries that support data aggregation, joins, sorting, and much more. Currently, only C# 3.0 and Visual Basic 9.0 offer complete
support for LINQ.
The middle level represents the three main parts of the LINQ project:
LINQ to Objects is an API that provides methods that represent a set of standard query operators (SQOs) to retrieve data from any object whose class implements the IEnumerable<T> interface. These queries are performed against in-memory data.
LINQ to ADO.NET augments SQOs to work against relational data. It is composed of three parts :
LINQ to SQL (formerly DLinq) is use to query relational databases such as Microsoft SQL Server.
LINQ to DataSet supports queries by using ADO.NET data sets and data tables.
LINQ to Entities is a Microsoft ORM solution, allowing developers to use Entities (an ADO.NET 3.0 feature) to declaratively specify the structure of business objects and use LINQ to query them.
LINQ to XML (formerly XLinq) not only augments SQOs but also includes a host of XMLspecific features for XML document creation and queries.

What You Need to Use LINQ

LINQ is a combination of extensions to .NET languages and class libraries that support them. To use it, you’ll need the following:
• LINQ, which is available from the LINQ Project website at http://msdn.microsoft.com/data/ref/linq. I’ve used the May 2006 CTP for this book.
• NET 2.0 running on Windows 2000 (Service Pack 4), Windows Server 2003, Windows XP Pro (Service Pack 2), or Windows Vista.
• To write C# programs using LINQ, you need either Visual Studio 2005 or Visual C# 2005 Express Edition.
• To use LINQ to ADO.NET, you need SQL Server 2005, SQL Server 2005 Express Edition, or SQL Server 2000.
• If you want to use LINQ with .NET 3.0 (originally WinFX), you need the WinFX Runtime Beta 2.

Advertisements