LINQ to SQL Basics – Part 3 (Select with “lazy loading”)

I will be using the Northwind database in this example.

Say you get the following requirements:

Show me all the Customers which ordered more than 5 items of Tofu between ’1998-03-06′ and ’1998-06-06′, and the Supplier which supplied the product.

Decoding the above requirements we will see that we need data from quite a few statements. So let’s see how the SQL select statement would look like for this:

select distinct ct.CompanyName CustomerName, s.CompanyName SupplierName

from [Order Details] od

inner
join Orders o

on o.OrderID = od.OrderID

inner
join Products p

on od.ProductID = p.ProductID

inner
join Suppliers s

on p.SupplierID = s.SupplierID

inner
join Customers ct

on ct.CustomerID = o.CustomerID

where o.OrderDate between
’1998-03-06′
and
’1998-06-06′

and p.[ProductName] =
‘Tofu’

and od.Quantity > 5

Quite a long and lumpy join… Something called “lazy loading” in LINQ make this big lumpy select a little bit simpler. You have instant access to the data that is joined to a specific table. Let’s have a look at how we could do this in LINQ.

var q = (from od in nw.Order_Details


where od.Order.OrderDate > DateTime.Parse(“1998-03-06″)

&& od.Order.OrderDate < DateTime.Parse(“1998-06-06″)

&& od.Product.ProductName == “Tofu”

&& od.Quantity > 5


select
new

{

CustomerName = od.Order.Customer.CompanyName,

SupplierName = od.Product.Supplier.CompanyName

}).Distinct();

As you can see we aren’t joining Order_Details up with any other tables. Let’s have a closer look using SQL profiler to see the actual SQL created:

exec
sp_executesql
N’SELECT DISTINCT [t3].[CompanyName] AS [CustomerName], [t4].[CompanyName] AS [SupplierName]

FROM [dbo].[Order Details] AS [t0]

INNER JOIN [dbo].[Orders] AS [t1] ON [t1].[OrderID] = [t0].[OrderID]

INNER JOIN [dbo].[Products] AS [t2] ON [t2].[ProductID] = [t0].[ProductID]

LEFT OUTER JOIN [dbo].[Customers] AS [t3] ON [t3].[CustomerID] = [t1].[CustomerID]

LEFT OUTER JOIN [dbo].[Suppliers] AS [t4] ON [t4].[SupplierID] = [t2].[SupplierID]

WHERE ([t1].[OrderDate] > @p0) AND ([t1].[OrderDate] < @p1) AND ([t2].[ProductName] = @p2) AND ([t0].[Quantity] > @p3)’,N’@p0 datetime,@p1 datetime,@p2 nvarchar(4),@p3 int’,@p0=’1998-03-06 00:00:00′,@p1=’1998-06-06 00:00:00′,@p2=N’Tofu’,@p3=5

Mmmmm…. Two outer joins…. Not what we wanted. Lets us try to change our LINQ query that it doesn’t produce the outer joins. To get past the outer joins we will have to remove some of the “lazy loading”. So the LINQ query will look as follow:

var q = (from od in nw.Order_Details


where od.Quantity > 5

&& od.Order.OrderDate > DateTime.Parse(“1998-03-06″)

&& od.Order.OrderDate < DateTime.Parse(“1998-06-06″)

&& od.Product.ProductName == “Tofu”


join ct in nw.Customers


on od.Order.CustomerID equals ct.CustomerID


join sp in nw.Suppliers


on od.Product.SupplierID equals sp.SupplierID


select
new

{

CustomerName = ct.CompanyName,

SupplierName = sp.CompanyName

}).Distinct();

We still using some of the lazy loading but just joining to Customers and Suppliers to get rid of the outer joins. The SQL query now looks as follow:

exec
sp_executesql
N’SELECT DISTINCT [t3].[CompanyName] AS [CustomerName], [t4].[CompanyName] AS [SupplierName]

FROM [dbo].[Order Details] AS [t0]

INNER JOIN [dbo].[Orders] AS [t1] ON [t1].[OrderID] = [t0].[OrderID]

INNER JOIN [dbo].[Products] AS [t2] ON [t2].[ProductID] = [t0].[ProductID]

INNER JOIN [dbo].[Customers] AS [t3] ON [t1].[CustomerID] = [t3].[CustomerID]

INNER JOIN [dbo].[Suppliers] AS [t4] ON [t2].[SupplierID] = ([t4].[SupplierID])

WHERE ([t0].[Quantity] > @p0) AND ([t1].[OrderDate] > @p1) AND ([t1].[OrderDate] < @p2) AND ([t2].[ProductName] = @p3)’,N’@p0 int,@p1 datetime,@p2 datetime,@p3 nvarchar(4)’,@p0=5,@p1=’1998-03-06 00:00:00′,@p2=’1998-06-06 00:00:00′,@p3=N’Tofu’

Just what we want! I recommend that you always use SQL profiler to inspect your queries and make sure that your SQL select statement looks the way that it should!

Advertisement
Published in: on April 8, 2009 at 2:02 pm  Leave a Comment  
Tags: , ,

The URI to TrackBack this entry is: http://mvkatredleaf.wordpress.com/2009/04/08/linqtosqlbasicspart3/trackback/

RSS feed for comments on this post.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.