0% found this document useful (0 votes)
134 views

LINQ To SQL Guide

This document discusses LINQ to SQL and provides examples of how to use it to query and modify a SQL database. It begins with an overview of LINQ to SQL and how to model databases using its designer. It then provides code examples for common tasks like querying, updating, inserting and deleting data. It also demonstrates calling stored procedures and implementing server-side paging. The document notes that LINQ to SQL uses lazy loading by default, which can hurt performance for queries that load related data. It shows how to retrieve supplier data along with the number of products, triggering multiple queries due to lazy loading.

Uploaded by

ahrenus
Copyright
© Attribution Non-Commercial (BY-NC)
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
134 views

LINQ To SQL Guide

This document discusses LINQ to SQL and provides examples of how to use it to query and modify a SQL database. It begins with an overview of LINQ to SQL and how to model databases using its designer. It then provides code examples for common tasks like querying, updating, inserting and deleting data. It also demonstrates calling stored procedures and implementing server-side paging. The document notes that LINQ to SQL uses lazy loading by default, which can hurt performance for queries that load related data. It shows how to retrieve supplier data along with the number of products, triggering multiple queries due to lazy loading.

Uploaded by

ahrenus
Copyright
© Attribution Non-Commercial (BY-NC)
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 9

Contents

What Is LINQ to SQL? ....................................................................................................................... 1 Modeling Databases Using LINQ to SQL: ...................................................................................... 1 LINQ to SQL Code Examples .......................................................................................................... 4 Summary ............................................................................................................................................. 6 Linq to SQL Lazy Loading in ASP.Net applications................................................................. 6 Entity Framework........................................................................................... Error! Bookmark not defined. Entity Framework Implementation................................................................ Error! Bookmark not defined. Differences between L2S and Entity Framework........................................... Error! Bookmark not defined. Performance .......................................................................................... Error! Bookmark not defined. Is LINQ2SQL deprecated?................................................................ Error! Bookmark not defined.

What Is LINQ to SQL?


Linq-to-SQL is Microsoft's first attempt at an ORM - Object-Relational Mapper. It supports SQL Server only. It's a mapping technology to map SQL Server database tables to .NET objects. You can then query the database using LINQ, as well as update/insert/delete data from it. This is the original LINQ provider for data access. LINQ to SQL fully supports transactions, views, and stored procedures. It also provides an easy way to integrate data validation and business logic rules into your data model.

Modeling Databases Using LINQ to SQL:


Visual Studio ships with a LINQ to SQL designer that provides an easy way to model and visualize a database as a LINQ to SQL object model. Using the LINQ to SQL designer we can easily create a representation of the sample "Northwind" database like below:

My LINQ to SQL design-surface above defines four entity classes: Product, Category, Order and OrderDetail. The properties of each class map to the columns of a corresponding table in the database. Each instance of a class entity represents a row within the database table. The arrows between the four entity classes above represent associations/relationships between the different entities. These are typically modeled using primary-key/foreignkey relationships in the database. The direction of the arrows on the design-surface indicate whether the association is a one-to-one or one-to-many relationship. Stronglytyped properties will be added to the entity classes based on this. For example, the Category class above has a one-to-many relationship with the Product class. This means it will have a "Categories" property which is a collection of Product objects within that category. The Product class then has a "Category" property that points to a Category class instance that represents the Category to which the Product belongs.

The right-hand method pane within the LINQ to SQL design surface above contains a list of stored procedures that interact with our database model. In the sample above I added a single "GetProductsByCategory" SPROC. It takes a categoryID as an input argument, and returns a sequence of Product entities as a result. We'll look at how to call this SPROC in a code sample below. Understanding the DataContext Class When you press the "save" button within the LINQ to SQL designer surface, Visual Studio will persist out .NET classes that represent the entities and database relationships that we modeled. For each LINQ to SQL designer file added to our solution, a custom DataContext class will also be generated. This DataContext class is the main conduit by which we'll query entities from the database as well as apply changes. The DataContext class created will have properties that represent each Table we modeled within the database, as well as methods for each Stored Procedure we added. For example, below is the NorthwindDataContext class that is persisted based on the model we designed above:

LINQ to SQL Code Examples


Once we've modeled our database using the LINQ to SQL designer, we can then easily write code to work against it. Below are a few code examples that show off common data tasks:
1) Query Products From the Database

The code below uses LINQ query syntax to retrieve an IEnumerable sequence of Product objects. Note how the code is querying across the Product/Category relationship to only retrieve those products in the "Beverages" category: C#:

2) Update a Product in the Database

The code below demonstrates how to retrieve a single product from the database, update its price, and then save the changes back to the database: C#:

3) Insert a New Category and Two New Products into the Database

The code below demonstrates how to create a new category, and then create two new products and associate them with the category. All three are then saved into the database. Note below how I don't need to manually manage the primary key/foreign key relationships. Instead, just by adding the Product objects into the category's "Products" collection, and then by adding the Category object into the DataContext's "Categories" collection, LINQ to SQL will know to automatically persist the appropriate PK/FK relationships for me. C#

4) Delete Products from the Database

The code below demonstrates how to delete all Toy products from the database: C#:

5) Call a Stored Procedure

The code below demonstrates how to retrieve Product entities not using LINQ query syntax, but rather by calling the "GetProductsByCategory" stored procedure we added to our data model above. Note that once I retrieve the Product results, I can update/delete them and then call db.SubmitChanges() to persist the modifications back to the database. C#:

6) Retrieve Products with Server Side Paging

The code below demonstrates how to implement efficient server-side database paging as part of a LINQ query. By using the Skip() and Take() operators below, we'll only return 10 rows from the database - starting with row 200. C#:

Summary
LINQ to SQL provides a nice, clean way to model the data layer of your application. Once you've defined your data model you can easily and efficiently perform queries, inserts, updates and deletes against it. Hopefully the above introduction and code samples have helped whet your appetite to learn more. Over the next few weeks I'll be continuing this series to explore LINQ to SQL in more detail.

Linq to SQL Lazy Loading in ASP.Net applications

In this section I would like to talk about LINQ to SQL and its native lazy loading functionality. I will show you how you can change this behavior. We will create a simple ASP.Net application to demonstrate this. I have seen a lot of people struggling with performance issues when it comes to LINQ to SQL. That is mostly due to the lack of knowledge of how LINQ internally works. Imagine that we have two tables Products and Suppliers (Northwind database). There is one to many relationship between those tables-entities. One supplier supplies many products. Let's say that we want to access a property from a related entity. We want to access a property from the Products entity through the Suppliers entity. The LINQ to SQL engine will create a query that will go and fetch the data at that very moment. This can be very bad for the performance of our application. Imagine the scenario that you want to retrieve rows of an entity and you need the related data as well. Let's say that you will return 1000 rows of the primary entity and its related data, that means another 1000 queries to the database. So keep in mind that lazy loading is enabled by default and I will prove that with an example. Then as I said before I will show you how to change that behavior. I assume that you have access to a version of SQL Server and Northwind database. If you do not, you can download and install the free SQL Server Express 2012 edition from here. If you need the installation scripts for the sample Northwind database, click here 1) Launch Visual Studio 2010/2008 (express editions will work fine). Create a new empty website and choose a suitable name for it. Choose C# as the development language. 2) Add a new item in your site. Add a LINQ to SQL Classes and name itNorthwind.dbml.Place this file in the App_Code special folder. 3) From the Server Explorer / Data Explorer window drag the Suppliers and theProducts tables and drop them on the Northwind.dbml. 4) We want to demonstrate the default lazy loading behavior of LINQ to SQL. I want to get the Supplier's contact name and the number of the products he/she supplies us. The second thing I want returned, lives in the related table of Products. In the Page_Load event handling routine of the Default.aspx type

NorthwindDataContext ctx = new NorthwindDataContext();

var mysuppliers = from suppl in ctx.Suppliers select suppl;

foreach (var supplier in mysuppliers) { Response.Write(supplier.ContactName); Response.Write("--");

Response.Write(supplier.Products.Count().ToString()); Response.Write("<br/>");

5) Before you run your application, in order to understand what hits your database and how often it does it, launch Profiler and start a new trace. Make sure you have included the events RPC:Starting,SQL:BatchStarting,SQL:BatchCompleted. 6) Run your application and see the results appearing in your screen but at the same time notice the number of sql queries hitting your database. In my case it looks something like this exec sp_executesql N'SELECT [t0].[ProductID], [t0].[ProductName], [t0].[SupplierID], [t0].[CategoryID], [t0].[QuantityPerUnit], [t0].[UnitPrice], [t0].[UnitsInStock], [t0].[UnitsOnOrder], [t0].[ReorderLevel], [t0].[Discontinued] FROM [dbo].[Products] AS [t0] WHERE [t0].[SupplierID] = @p0',N'@p0 int',@p0=1

then I have a huge number of almost identical dynamic sql queries hitting my database. exec sp_executesql N'SELECT [t0].[ProductID], [t0].[ProductName], [t0].[SupplierID], [t0].[CategoryID], [t0].[QuantityPerUnit], [t0].[UnitPrice], [t0].[UnitsInStock], [t0].[UnitsOnOrder], [t0].[ReorderLevel], [t0].[Discontinued] FROM [dbo].[Products] AS [t0] WHERE [t0].[SupplierID] = @p0',N'@p0 int',@p0=2

exec sp_executesql N'SELECT [t0].[ProductID], [t0].[ProductName], [t0].[SupplierID], [t0].[CategoryID], [t0].[QuantityPerUnit], [t0].[UnitPrice], [t0].[UnitsInStock], [t0].[UnitsOnOrder], [t0].[ReorderLevel], [t0].[Discontinued] FROM [dbo].[Products] AS [t0] WHERE [t0].[SupplierID] = @p0',N'@p0 int',@p0=3 exec sp_executesql N'SELECT [t0].[ProductID], [t0].[ProductName], [t0].[SupplierID], [t0].[CategoryID], [t0].[QuantityPerUnit], [t0].[UnitPrice], [t0].[UnitsInStock], [t0].[UnitsOnOrder], [t0].[ReorderLevel], [t0].[Discontinued] FROM [dbo].[Products] AS [t0] WHERE [t0].[SupplierID] = @p0',N'@p0 int',@p0=4

and the story goes on and on.They are all identical just passing in a new SupplierID value. This is not good for my application. 7) We can change this so we do not hit our database so many times.In the Page_Loadevent handling routine type (immediately after the NorthwindDataContext ctx = new NorthwindDataContext();) those two lines below:

DataLoadOptions dlo = new DataLoadOptions(); dlo.LoadWith<Supplier>(s => s.Products);

ctx.LoadOptions = dlo;
Do not forget to include the using System.Data.Linq; We are basically telling LINQ engine that whenever it does fetch data from our database regarding Supplier entity/table, to fetch the Products related data as well. 8) Run your application again. Before you do that make sure you start a new trace with the events RPC:Starting,SQL:BatchStarting,SQL:BatchCompleted included. You will see the results in your screen but have a look at the Trace output as well. We do not have so many sql statements anymore hitting our database.The one that appears in my case is this one

SELECT [t0].[SupplierID], [t0].[CompanyName], [t0].[ContactName], [t0].[ContactTitle], [t0].[Address], [t0].[City], [t0].[Region], [t0].[PostalCode], [t0].[Country], [t0].[Phone], [t0].[Fax], [t0].[HomePage], [t1].[ProductID], [t1].[ProductName], [t1].[SupplierID] AS [SupplierID2], [t1].[CategoryID], [t1].[QuantityPerUnit], [t1].[UnitPrice], [t1].[UnitsInStock], [t1].[UnitsOnOrder], [t1].[ReorderLevel], [t1].[Discontinued], ( SELECT COUNT(*) FROM [dbo].[Products] AS [t2] WHERE [t2].[SupplierID] = [t0].[SupplierID] ) AS [value] FROM [dbo].[Suppliers] AS [t0] LEFT OUTER JOIN [dbo].[Products] AS [t1] ON [t1].[SupplierID] = [t0].[SupplierID] ORDER BY [t0].[SupplierID], [t1].[ProductID]
9) So now we have instead of lazy loading, eager loading. Hope it all makes sense now. The main point is to know how everything works (in this case LINQ to SQL ) and how this affects the performance of our application.

You might also like