Go to DotNetFunda.com
 Online : 1868 |  Welcome, Guest!   Login
 
Home > Articles > ASP.NET > Optimizing LINQ Queries using DataLoadOptions

  • Download the OOPS, ASP.NET and ADO.NET Training Videos for FREE, click here.

Submit Article | Articles Home | Search Articles |

Optimizing LINQ Queries using DataLoadOptions

 Download source file
 Posted on: 7/4/2009 2:29:16 AM by Questpond | Views: 675 | Category: ASP.NET | Level: Advance | Print Article
In this section we will understand the round trip issues of LINQ and how we can overcome the same using ‘DataLoadOptions’. One of the biggest issues with LINQ to SQL is that it fires SQL query for every object which has a huge impact on performance. In this article we will see how we can get all data in one SQL Query.

.NET Training Videos!
Buy online comprehensive training video pack just for $35.00 only, see what's inside it.

 

 

 

 

 

Optimizing LINQ Queries using DataLoadOptions

Introduction

LINQ basics

Customer , Addresses and Phones LINQ entities

Analyzing the LINQ SQL round trips

Avoiding round trips using DataLoadOptions

Source code

Introduction
 

Thanks to everyone who have knowingly / unknowingly helped me to become Microsoft MVP, hope I can live to it.

In this section we will understand the round trip issues of LINQ and how we can overcome the same using ‘DataLoadOptions’. One of the biggest issues with LINQ to SQL is that it fires SQL query for every object which has a huge impact on performance. In this article we will see how we can get all data in one SQL Query.



Catch my videos for WCF, WPF, WWF, LINQ, SilverLight, Design patterns, UML and lot on http://www.questpond.com
 

LINQ basics
 

This article assumes that you have a basic knowledge of how entity objects can be flourished using LINQ. In case you are not aware of basics of LINQ to SQL mapping you can read my article to understand the basic LINQ concepts from :- http://www.dotnetfunda.com/articles/article446-onemany-and-oneone-relationship-using-linq-to-sql.aspx .
 

Customer , Addresses and Phones LINQ entities
 

First let’s try to understand how LINQ queries actually work and then we will see how round trips happen. Let’s consider the below database design where we have 3 tables customer, addresses and phone. There is one-many relationship between customer and addresses, while there is one-one relationship between address table and phones.
 

We have created three entities as per the table design i.e. ‘ClsCustomerWithAddresses’,’ClsAddresses’ and ‘ClsPhone’. We have defined the relationships between them using ‘EntitySet’ and ‘EntityRef’.

To fill the entity objects with data from table is a 5 step process. As a first step the datacontext connection is created using the connection string, LINQ query is created and then we start browsing through customer, address and phones.

Analyzing the LINQ SQL round trips
 

Ok, now that we have analyzed that it takes 5 steps to execute a LINQ query. So let’s try to figure out on which step does the LINQ query actually fire SQL to the database. So what we will do is we will run the above LINQ code and analyze the same using SQL profiler.

Just so that we do not catch with lot of SQL Server noise we have only enabled RPC and SQL batch events.
 

Now when you run the query you will find the below things:-
• The execution of actual SQL takes place when the for each statement is iterated on the LINQ objects.
• The second very stunning thing you will notice is that for every entity separate query is fired to SQL Server. For instance for customer one query is fired and then separate queries for address and phones are fired to flourish the entity object. In other words lot of round trips.
 

Avoiding round trips using DataLoadOptions
 

We can instruct LINQ engine to load all the objects using ‘DataLoadOptions’. Below are the steps involved to enable ‘DataLoadOptions’.

The first step is to create the data context class.
 

DataContext objContext = new DataContext(strConnectionString);

Second step is to create the ‘DataLoadOption’ object.
 

DataLoadOptions objDataLoadOption = new DataLoadOptions();

Using the LoadWith method we need to define that we want to load customer with address in one SQL.
 

objDataLoadOption.LoadWith<clsCustomerWithAddresses>(clsCustomerWithAddresses => clsCustomerWithAddresses.Addresses);

Every address object has phone object , so we have also defined saying that the phone objects should be loaded for every address object in one SQL.
 

objDataLoadOption.LoadWith<clsAddresses>(clsAddresses => clsAddresses.Phone);

Whatever load option you have defined you need to set the same to the data context object using ‘LoadOptions’ property.
 

objContext.LoadOptions = objDataLoadOption;

Finally prepare you query.
 

var MyQuery = from objCustomer in objContext.GetTable<clsCustomerWithAddresses>()
select objCustomer;

Start looping through the objects.
 

foreach (clsCustomerWithAddresses objCustomer in MyQuery)
{

Response.Write(objCustomer.CustomerName + "<br>");

foreach (clsAddresses objAddress in objCustomer.Addresses)
{
Response.Write("===Address:- " + objAddress.Address1 + "<br>");
Response.Write("========Mobile:- " + objAddress.Phone.MobilePhone + "<br>");
Response.Write("========LandLine:- " + objAddress.Phone.LandLine + "<br>");
}
}

Below is the complete source code for the same.
 

DataContext objContext = new DataContext(strConnectionString);
DataLoadOptions objDataLoadOption = new DataLoadOptions();
objDataLoadOption.LoadWith<clsCustomerWithAddresses>(clsCustomerWithAddresses => clsCustomerWithAddresses.Addresses);
objDataLoadOption.LoadWith<clsAddresses>(clsAddresses => clsAddresses.Phone);
objContext.LoadOptions = objDataLoadOption;
var MyQuery = from objCustomer in objContext.GetTable<clsCustomerWithAddresses>()
select objCustomer;

foreach (clsCustomerWithAddresses objCustomer in MyQuery)
{

Response.Write(objCustomer.CustomerName + "<br>");

foreach (clsAddresses objAddress in objCustomer.Addresses)
{
Response.Write("===Address:- " + objAddress.Address1 + "<br>");
Response.Write("========Mobile:- " + objAddress.Phone.MobilePhone + "<br>");
Response.Write("========LandLine:- " + objAddress.Phone.LandLine + "<br>");
}
}

Abracadabra…. Now if you run the code LINQ has executed only one SQL with proper joins as compared to 3 SQL for every object shown previously.
 

Source code
 

We have also attached a source code. Run the project and see how profiler shows different SQL execution. You can first run the ‘EntitySet’ example and see how SQL profiler reacts for the same and then run the example with ‘DataLoadOptions’. The SQL script is attached in a different file.
 


If you like this article, subscribe to our RSS Feed. You can also subscribe via email to our Interview Questions, Codes and Forums section.

Interesting?   Share and Bookmark this kick it on DotNetKicks.com


Experience:0 year(s)
Home page:http://www.questpond.com
Member since:Wednesday, September 03, 2008
Level:HonoraryPlatinum
Status: [PanelMember] [Member] [MVP] [Administrator]
Biography:I am a Microsoft MVP for ASP/ASP.NEt and currently a CEO of a small E-learning company in India. We are very much active in making training videos , writing books and corporate trainings. You can visit about my organization at http://www.questpond.com and also enjoy the videos uploaded for Design pattern, FPA , UML ,Share Point,WCF,WPF,WWF,LINQ, Project and lot. I am also actively involved in RFC which is a financial open source madei in C#. It has modules like accounting , invoicing , purchase , stocks etc.
 Latest post(s) from Questpond

   ◘ 4 steps to consume web services using Ajax (Includes Video tutorial) posted on 2/20/2010 9:16:32 AM
   ◘ 7 simple steps to run your first Azure Queue program posted on 2/11/2010 12:48:49 AM
   ◘ Simple 5 steps to expose WCF services using REST style posted on 2/1/2010 5:50:38 AM
   ◘ SQL Query Optimization FAQ Part 1 (With video explanation) posted on 1/28/2010 5:34:05 AM
   ◘ Simple 7 steps to run your first Azure Blob Program posted on 1/24/2010 7:08:28 AM


Submit Article

About Us | The Team | Advertise | Contact Us | Feedback | Privacy Policy | Terms of Use | Link Exchange | Members | Go Top
General Notice: If you found copied contents on this page, please let us know the original source along with your correct email id (to communicate) for further action.
All rights reserved to DotNetFunda.Com. Logos, company names used here if any are only for reference purposes and they may be respective owner's right or trademarks.
(Best viewed in IE 6.0+ or Firefox 2.0+ at 1024 * 768 or higher)