This is an introductory article that focuses on basic querying using “LINQ to SQL.” It covers basic LINQ operators with both SQL and LINQ examples. If you are new to programming LINQ, please consider reading my previous articles, called “Beginning ‘LINQ to SQL’ using Visual Studio 2008” and “Introducing ‘LINQ to SQL’ designer using Visual Studio 2008.”
All the queries in this article will focus on the above model. The image is linked to here due to size and clarity considerations.
The entire source code for this article is available in the form of a free downloadable zip file (CS and VB). The solution was developed using Microsoft Visual Studio 2008 Team Edition on Microsoft Windows Server 2003 Standard Edition with Microsoft SQL Server 2005 Developer Edition. I didn’t really test it in any other environment. I request that you post in the discussion area if you have any problems regarding execution.
Beginning to fetch data using LINQ (i.e. fetching rows from a table)
To begin fetching data, you must start with a query. As we already have a model created using “LINQ to SQL Designer,” we will start fetching data from that model using LINQ.
In general, to retrieve all rows from the Regions table, we would write a SQL SELECT as follows:
SELECT * FROM Region
The LINQ statement (in VB) for the above SELECT can be written as follows:
Dim q = From p In db.Regions _
Select p
To make it simpler, we can even omit the “Select” part as follows (only in VB):
Dim q = From p In db.Regions
The complete code for the above examples would be as follows:
Protected Sub btnSelectFromRegions_Click(ByVal sender As Object, ByVal e As EventArgs) Handles btnSelectFromRegions.Click
NorthwindDataContext db = new NorthwindDataContext();
StringWriter s = new StringWriter();
db.Log = s;
var q = (from p in db.Orders
select p.CustomerID).Distinct() ;
this.GridView1.DataSource = q;
this.GridView1.DataBind();
this.lblGenSQL.Text = s.ToString();
}
What if I have this query:
SELECT DISTINCT CustomerID, EmployeeID FROM Orders
The above query returns all rows with CustomerID and EmployeeID without repetition (combined DISTINCT and not individual DISTINCT). That means CustomerID and EmployeeID can repeat alone, but cannot repeat combined.
To make this possible using LINQ (in VB), the query would be as follows:
Dim q = From p In db.Orders _
Select p.CustomerID, p.EmployeeID Distinct
The same in C# would be as follows:
var q = (from p in db.Orders
select new { p.CustomerID, p.EmployeeID }).Distinct();
“WHERE” is one of the most important operators in LINQ and is used to filter rows. Let us imagine that we have the following SELECT query:
SELECT OrderID, OrderDate, Freight
FROM Orders
WHERE Freight > 500 AND Freight < 800
The relevant LINQ (in VB) would be as follows:
Dim q = From p In db.Orders _
Where p.Freight > 500 And p.Freight < 800 _
Select p.OrderID, p.OrderDate, p.Freight
The same thing in C# would be as follows:
var q = from p in db.Orders
where p.Freight > 500 && p.Freight < 800
orderby p.Freight descending
select new { p.OrderID, p.OrderDate, p.Freight };
The WHERE operator in a SELECT statement is equipped with several SQL operators, such as IN, LIKE, IS NULL, etc. LINQ does not directly support a few of those operators. Instead, we will have to trick LINQ using the .NET Framework. Let us see how.
The following SELECT query...
SELECT OrderID, OrderDate, Freight
FROM Orders
WHERE OrderID IN (10257, 10300, 10292)
can be written in LINQ (in VB) as follows:
Dim arOrderIDs() As Integer = {10257, 10300, 10292}
Dim q = From p In db.Orders _
Where arOrderIDs.Contains(p.OrderID) _
Select p.OrderID, p.OrderDate, p.Freight
The NOT can be implemented as follows:
Dim q = From p In db.Orders _
Where Not (arOrderIDs.Contains(p.OrderID)) _
Select p.OrderID, p.OrderDate, p.Freight
In C# (including the NOT operator), the same thing looks like the following:
int[] arOrderIDs = new int[] { 10257, 10300, 10292 };
“LIKE” is another important operator in SQL that filters rows on string patterns. The LINQ syntax of VB.NET 2008 has great flexibility in terms of using the LIKE operator. If you are familiar with SQL LIKE, you should easily understand the following examples:
Dim q = From p In db.Customers _
Where p.CompanyName Like "A*" _
Select p.CustomerID, p.ContactName, p.CompanyName
Dim q = From p In db.Customers _
Where p.CompanyName Like "?A*" _
Select p.CustomerID, p.ContactName, p.CompanyName
Dim q = From p In db.Customers _
Where Not (p.CompanyName Like "?A*") _
Select p.CustomerID, p.ContactName, p.CompanyName
C# does not directly support the LIKE operator in LINQ. Instead, we have to work as follows:
var q = from p in db.Customers
where System.Data.Linq.SqlClient.SqlMethods.Like(p.CompanyName, "_A%")
select new { p.CustomerID, p.ContactName, p.CompanyName };
Make sure that SqlMethods is not compulsory and just for flexibility. If you can achieve the same thing using built-in .NET Framework functions (like string functions), you can also use them in the conditional expressions.
Now, let us see how we can work with NULLs using LINQ. Consider the following VB.NET statement:
select new { p.CustomerID, p.ContactName, p.Region };
var q = from p in db.Customers
where p.Region != null
select new { p.CustomerID, p.ContactName, p.Region };
We will go further in-depth in my upcoming articles. I hope you enjoyed this article and any suggestions, bugs, errors, enhancements etc. are highly appreciated at http://jagchat.spaces.live.com.