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

LINQ To SQL

The document discusses LINQ to SQL, which allows .NET developers to model and query relational databases using .NET classes and LINQ queries. It describes how to create a LINQ to SQL data model using Visual Studio's designer by mapping database tables to classes and relationships. Code examples are provided to demonstrate common data tasks like querying, updating, inserting and deleting data using the generated DataContext class.

Uploaded by

Antonio Lima
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
130 views

LINQ To SQL

The document discusses LINQ to SQL, which allows .NET developers to model and query relational databases using .NET classes and LINQ queries. It describes how to create a LINQ to SQL data model using Visual Studio's designer by mapping database tables to classes and relationships. Code examples are provided to demonstrate common data tasks like querying, updating, inserting and deleting data using the generated DataContext class.

Uploaded by

Antonio Lima
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 107

Using LINQ to SQL (Part 1)

Over the last few months I wrote a series of blog posts that covered some of the new language features
that are coming with the Visual Studio and .NET Framework "Orcas" release. Here are pointers to the
posts in my series:
Automatic Properties, Object Initializer and Collection Initializers
Extension Methods
Lambda Expressions
Query Syntax
Anonymous Types
The above language features help make querying data a first class programming concept. We call this
overall querying programming model "LINQ" - which stands for .NET Language Integrated Query.
Developers can use LINQ with any data source. They can express efficient query behavior in their
programming language of choice, optionally transform/shape data query results into whatever format they
want, and then easily manipulate the results. LINQ-enabled languages can provide full type-safety
and compile-time checking of query expressions, and development tools can provide full intellisense,
debugging, and rich refactoring support when writing LINQ code.
LINQ supports a very rich extensibility model that facilitates the creation of very efficient domain-specific
operators for data sources. The "Orcas" version of the .NET Framework ships with built-in libraries that
enable LINQ support against Objects, XML, and Databases.
What Is LINQ to SQL?
LINQ to SQL is an O/RM (object relational mapping) implementation that ships in the .NET Framework
"Orcas" release, and which allows you to model a relational database using .NET classes. You can then
query the database using LINQ, as well as update/insert/delete data from it.
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 "Orcas" 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. My next blog post will cover in more depth how to use this
designer (you can also watch this video I made in January to see me build a LINQ to SQL model from
scratch using it).
Using the LINQ to SQL designer I can easily create a representation of the sample "Northwind" database
like below:
Page 1of 37
UsingLINQtoSQL (Part 1) - ScottGu'sBlog
2008/09/18
file://N:\Programming\KB\Programming\using- linq- to- sql- part- 1.aspx.htm
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/foreign-key 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. Strongly-typed 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
Page 2of 37 Using LINQ to SQL (Part 1) - ScottGu's Blog
2008/09/18 file://N:\Programming\KB\Programming\using-linq-to-sql-part-1.aspx.htm
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#:

Page 3of 37 Using LINQ to SQL (Part 1) - ScottGu's Blog
2008/09/18 file://N:\Programming\KB\Programming\using-linq-to-sql-part-1.aspx.htm
VB:

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#:

VB:

Note: VB in "Orcas" Beta1 doesn't support Lambdas yet. It will, though, in Beta2 - at which point the
above query can be rewritten to be more concise.
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#
Page 4of 37 Using LINQ to SQL (Part 1) - ScottGu's Blog
2008/09/18 file://N:\Programming\KB\Programming\using-linq-to-sql-part-1.aspx.htm

VB:

4) Delete Products from the Database
The code below demonstrates how to delete all Toy products from the database:
C#:
Page 5of 37 Using LINQ to SQL (Part 1) - ScottGu's Blog
2008/09/18 file://N:\Programming\KB\Programming\using-linq-to-sql-part-1.aspx.htm

VB:

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#:

VB:
Page 6of 37 Using LINQ to SQL (Part 1) - ScottGu's Blog
2008/09/18 file://N:\Programming\KB\Programming\using-linq-to-sql-part-1.aspx.htm

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#:

VB:

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.
Hope this helps,
Scott
Page 7of 37 Using LINQ to SQL (Part 1) - ScottGu's Blog
2008/09/18 file://N:\Programming\KB\Programming\using-linq-to-sql-part-1.aspx.htm
LINQ to SQL (Part 2 - Defining our Data Model
Classes)
In Part 1 of my LINQ to SQL blog post series I discussed "What is LINQ to SQL" and provided a
basic overview of some of the data scenarios it enables.
In my first post I provided code samples that demonstrated how to perform common data scenarios using
LINQ to SQL including:
How to query a database
How to update rows in a database
How to insert and relate multiple rows in a database
How to delete rows in a database
How to call a stored procedure
How to retrieve data with server-side paging
I performed all of these data scenarios using a LINQ to SQL class model that looked like the one below:
In this second blog post in the series I'm going to go into more detail on how to create the above LINQ to
Page 1of 28
LINQtoSQL (Part 2- Definingour DataModel Classes) - ScottGu'sBlog
2008/09/18
file://N:\Programming\KB\Programming\linq- to- sql- part- 2- defining- our- data- mo...
SQL data model.
LINQ to SQL, the LINQ to SQL Designer, and all of the features that I'm covering in this blog post series
will ship as part of the .NET 3.5 and Visual Studio "Orcas" release.
You can follow all of the steps below by downloading either Visual Studio "Orcas" Beta 1 or Visual Web
Developer Express "Orcas" Beta1. Both can be installed and used side-by-side with VS 2005.
Create a New LINQ to SQL Data Model
You can add a LINQ to SQL data model to an ASP.NET, Class Library or Windows client project by using
the "Add New Item" option within Visual Studio and selecting the "LINQ to SQL" item within it:
Selecting the "LINQ to SQL" item will launch the LINQ to SQL designer, and allow you to model classes
that represent a relational database. It will also create a strongly-typed "DataContext" class that will have
properties that represent each Table we modeled within the database, as well as methods for each Stored
Procedure we modeled. As I described in Part 1 of this blog post series, the DataContext class is the main
conduit by which we'll query entities from the database as well as apply changes back to it.
Below is a screen-shot of an empty LINQ to SQL ORM designer surface, and is what you'll see
immediately after creating a new LINQ to SQL data model:
Page 2of 28 LINQ to SQL (Part 2 - Defining our Data Model Classes) - ScottGu's Blog
2008/09/18 file://N:\Programming\KB\Programming\linq-to-sql-part-2-defining-our-data-model-...
Entity Classes
LINQ to SQL enables you to model classes that map to/from a database. These classes are typically
referred to as "Entity Classes" and instances of them are called "Entities". Entity classes map to tables
within a database. The properties of entity classes typically map to the table's columns. Each instance of
an entity class then represents a row within the database table.
Entity classes defined with LINQ to SQL do not have to derive from a specific base class, which means
that you can have them inherit from any object you want. All classes created using the LINQ to SQL
designer are defined as "partial classes" - which means that you can optionally drop into code and add
additional properties, methods and events to them.
Unlike the DataSet/TableAdapter feature provided in VS 2005, when using the LINQ to SQL designer you
do not have to specify the SQL queries to use when creating your data model and access layer.
Instead, you focus on defining your entity classes, how they map to/from the database, and the
relationships between them. The LINQ to SQL OR/M implementation will then take care of generating the
appropriate SQL execution logic for you at runtime when you interact and use the data entities. You can
use LINQ query syntax to expressively indicate how to query your data model in a strongly typed way.
Creating Entity Classes From a Database
If you already have a database schema defined, you can use it to quickly create LINQ to SQL entity
classes modeled off of it.
The easiest way to accomplish this is to open up a database in the Server Explorer within Visual Studio,
select the Tables and Views you want to model in it, and drag/drop them onto the LINQ to SQL designer
surface:
Page 3of 28 LINQ to SQL (Part 2 - Defining our Data Model Classes) - ScottGu's Blog
2008/09/18 file://N:\Programming\KB\Programming\linq-to-sql-part-2-defining-our-data-model-...

When you add the above 2 tables (Categories and Products) and 1 view (Invoices) from the "Northwind"
database onto the LINQ to SQL designer surface, you'll automatically have the following three entity
classes created for you based on the database schema:
Page 4of 28 LINQ to SQL (Part 2 - Defining our Data Model Classes) - ScottGu's Blog
2008/09/18 file://N:\Programming\KB\Programming\linq-to-sql-part-2-defining-our-data-model-...

Using the data model classes defined above, I can now run all of the code samples (expect the SPROC
one) described in Part 1 of this LINQ to SQL series. I don't need to add any additional code or
configuration in order to enable these query, insert, update, delete, and server-side paging scenarios.
Naming and Pluralization
One of the things you'll notice when using the LINQ to SQL designer is that it automatically "pluralizes" the
various table and column names when it creates entity classes based on your database schema. For
example: the "Products" table in our example above resulted in a "Product" class, and the "Categories"
table resulted in a "Category" class. This class naming helps make your models consistent with the .NET
naming conventions, and I usually find having the designer fix these up for me really convenient
(especially when adding lots of tables to your model).
If you don't like the name of a class or property that the designer generates, though, you can always
override it and change it to any name you want. You can do this either by editing the entity/property name
in-line within the designer or by modifying it via the property grid:

The ability to have entity/property/association names be different from your database schema ends up
being very useful in a number of cases. In particular:
1) When your backend database table/column schema names change. Because your entity models can
have different names from the backend schema, you can decide to just update your mapping rules and
not update your application or query code to use the new table/column name.
Page 5of 28 LINQ to SQL (Part 2 - Defining our Data Model Classes) - ScottGu's Blog
2008/09/18 file://N:\Programming\KB\Programming\linq-to-sql-part-2-defining-our-data-model-...
2) When you have database schema names that aren't very "clean". For example, rather than use
"au_lname" and "au_fname" for the property names on an entity class, you can just name them to
"LastName" and "FirstName" on your entity class and develop against that instead (without having to
rename the column names in the database).
Relationship Associations
When you drag objects from the server explorer onto the LINQ to SQL designer, Visual Studio will inspect
the primary key/foreign key relationships of the objects, and based on them automatically create
default "relationship associations" between the different entity classes it creates. For example, when I
added both the Products and Categories tables from Northwind onto my LINQ to SQL designer you can
see that a one to many relationship between the two is inferred (this is denoted by the arrow in the
designer):

The above association will cause cause the Product entity class to have a "Category" property that
developers can use to access the Category entity for a given Product. It will also cause the Category
class to have a "Products" collection that enables developers to retrieve all products within that Category.

If you don't like how the designer has modeled or named an association, you can always override it. J ust
click on the association arrow within the designer and access its properties via the property grid to
Page 6of 28 LINQ to SQL (Part 2 - Defining our Data Model Classes) - ScottGu's Blog
2008/09/18 file://N:\Programming\KB\Programming\linq-to-sql-part-2-defining-our-data-model-...
rename, delete or modify it.
Delay/Lazy Loading
LINQ to SQL enables developers to specify whether the properties on entities should be prefetched or
delay/lazy-loaded on first access. You can customize the default pre-fetch/delay-load rules for entity
properties by selecting any entity property or association in the designer, and then within the property-grid
set the "Delay Loaded" property to true or false.
For a simple example of when I'd want to-do this, consider the "Category" entity class we modeled above.
The categories table inside "Northwind" has a "Picture" column which stores a (potentially large) binary
image of each category, and I only want to retrieve the binary image from the database when I'm actually
using it (and not when doing a simply query just to list the category names in a list).
I could configure the Picture property to be delay loaded by selecting it within the LINQ to SQL designer
and by settings its Delay Loaded value in the property grid:

Note: In addition to configuring the default pre-fetch/delay load semantics on entities, you can also
override them via code when you perform LINQ queries on the entity class (I'll show how to-do this in the
next blog post in this series).
Using Stored Procedures
LINQ to SQL allows you to optionally model stored procedures as methods on your DataContext class.
For example, assume we've defined the simple SPROC below to retrieve product information based on a
categoryID:
Page 7of 28 LINQ to SQL (Part 2 - Defining our Data Model Classes) - ScottGu's Blog
2008/09/18 file://N:\Programming\KB\Programming\linq-to-sql-part-2-defining-our-data-model-...

I can use the server explorer within Visual Studio to drag/drop the SPROC onto the LINQ to SQL designer
surface in order to add a strongly-typed method that will invoke the SPROC. If I drop the SPROC on top
of the "Product" entity in the designer, the LINQ to SQL designer will declare the SPROC to return an
IEnumerable<Product>result:
I can then use either LINQ Query Syntax (which will generate an adhoc SQL query) or alternatively invoke
the SPROC method added above to retrieve product entities from the database:
Page 8of 28 LINQ to SQL (Part 2 - Defining our Data Model Classes) - ScottGu's Blog
2008/09/18 file://N:\Programming\KB\Programming\linq-to-sql-part-2-defining-our-data-model-...

Using SPROCs to Update/Delete/Insert Data
By default LINQ to SQL will automatically create the appropriate SQL expressions for you when you
insert/update/delete entities. For example, if you wrote the LINQ to SQL code below to update some
values on a "Product" entity instance:

By default LINQ to SQL would create and execute the appropriate "UPDATE" statement for you when you
submitted the changes (I'll cover this more in a later blog post on updates).
You can also optionally define and use custom INSERT, UPDATE, DELETE sprocs instead. To configure
these, just click on an entity class in the LINQ to SQL designer and within its property-grid click the "..."
button on the Delete/Insert/Update values, and pick a particular SPROC you've defined instead:
Page 9of 28 LINQ to SQL (Part 2 - Defining our Data Model Classes) - ScottGu's Blog
2008/09/18 file://N:\Programming\KB\Programming\linq-to-sql-part-2-defining-our-data-model-...

What is nice about changing the above setting is that it is done purely at the mapping layer of LINQ to SQL
- which means the update code I showed earlier continues to work with no modifications required. This
avoids developers using a LINQ to SQL data model from having to change code even if they later decide
to put in a custom SPROC optimization later.
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.
Using the built-in LINQ to SQL designer within Visual Studio and Visual Web Developer Express you can
create and manage your data models for LINQ to SQL extremely fast. The LINQ to SQL designer also
provides a lot of flexibility that enables you to customize the default behavior and override/extend the
system to meet your specific needs.
In upcoming posts I'll be using the data model we created above to drill into querying, inserts, updates and
deletes further. In the update, insert and delete posts I'll also discuss how to add custom business/data
validation logic to the entities we designed above to perform additional validation logic.
Mike Taulty also has a number of great LINQ to SQL videos that I recommend checking out here. These
provide a great way to learn by watching someone walkthrough using LINQ to SQL in action.
Hope this helps,
Scott
Published Tuesday, May 29, 2007 1:17 AM by ScottGu
Filed under: ASP.NET, Visual Studio, .NET, LINQ, Data

Comments
# re: LINQ to SQL (Part 2 - Defining our Data Model Classes)
Page 10of 28 LINQ to SQL (Part 2 - Defining our Data Model Classes) - ScottGu's Blog
2008/09/18 file://N:\Programming\KB\Programming\linq-to-sql-part-2-defining-our-data-model-...
LINQ to SQL (Part 3 - Querying our Database)
Last month I started a blog post series covering LINQ to SQL. LINQ to SQL is a built-in O/RM (object
relational mapping) framework that ships in the .NET Framework 3.5 release, and which enables you to
easily model relational databases using .NET classes. You can then use LINQ expressions to query the
database with them, as well as update/insert/delete data from it.
Below are the first two parts of my LINQ to SQL series:
Part 1: Introduction to LINQ to SQL
Part 2: Defining our Data Model Classes
In today's blog post I'll be going into more detail on how to use the data model we created in the Part 2
post, and show how to use it to query data within an ASP.NET project.
Northwind Database Modeled using LINQ to SQL
In Part 2 of this series I walked through how to create a LINQ to SQL class model using the LINQ to SQL
designer that is built-into VS 2008. Below is the class model that we created for the Northwind sample
database:
Page 1of 33
LINQtoSQL (Part 3- Queryingour Database) - ScottGu'sBlog
2008/09/18
file://N:\Programming\KB\Programming\linq- to- sql- part- 3- querying- our- database...
Retrieving Products
Once we have defined our data model classes above, we can easily query and retrieve data from our
database. LINQ to SQL enables you to do this by writing LINQ syntax queries against the
NorthwindDataContext class that we created using the LINQ to SQL designer above.
For example, to retrieve and iterate over a sequence of Product objects I could write code like below:
Page 2of 33 LINQ to SQL (Part 3 - Querying our Database) - ScottGu's Blog
2008/09/18 file://N:\Programming\KB\Programming\linq-to-sql-part-3-querying-our-database.as...

In the query above I have used a "where" clause in my LINQ syntax query to only return those products
within a specific category. I am using the CategoryID of the Product to perform the filter.
One of the nice things above LINQ to SQL is that I have a lot of flexibility in how I query my data, and I can
take advantage of the associations I've setup when modeling my LINQ to SQL data classes to perform
richer and more natural queries against the database. For example, I could modify the query to filter by
the product's CategoryName instead of its CategoryID by writing my LINQ query like so:

Notice above how I'm using the "Category" property that is on each of the Product objects to filter by the
CategoryName of the Category that the Product belongs to. This property was automatically created for
us by LINQ to SQL because we modeled the Category and Product classes as having a many to one
relationship with each other in the database.
For another simple example of using our data model's association relationships within queries, we could
write the below LINQ query to retrieve only those products that have had 5 or more orders placed for
them:

Notice above how we are using the "OrderDetails" collection that LINQ to SQL has created for us on each
Product class (because of the 1 to many relationship we modeled in the LINQ to SQL designer).
Visualizing LINQ to SQL Queries in the Debugger
Page 3of 33 LINQ to SQL (Part 3 - Querying our Database) - ScottGu's Blog
2008/09/18 file://N:\Programming\KB\Programming\linq-to-sql-part-3-querying-our-database.as...
Object relational mappers like LINQ to SQL handle automatically creating and executing the appropriate
SQL code for you when you perform a query or update against their object model.
One of the biggest concerns/fears that developers new to ORMs have is "but what SQL code is it actually
executing?" One of the really nice things about LINQ to SQL is that it makes it super easy to see exactly
what SQL code it is executing when you run your application within the debugger.
Starting with Beta2 of Visual Studio 2008 you can use a new LINQ to SQL visualizer plug-in to easily see
(and test out) any LINQ to SQL query expression. Simply set a breakpoint and then hover over a LINQ to
SQL query and click the magnify glass to pull up its expression visualizer within the debugger:

This will then bring up a dialog that shows you the exact SQL that LINQ to SQL will use when executing
the query to retrieve the Product objects:
If you press the "Execute" button within this dialog it will allow you to evaluate the SQL directly within the
debugger and see the exact data results returned from the database:
Page 4of 33 LINQ to SQL (Part 3 - Querying our Database) - ScottGu's Blog
2008/09/18 file://N:\Programming\KB\Programming\linq-to-sql-part-3-querying-our-database.as...
This obviously makes it super easy to see precisely what SQL query logic LINQ to SQL is doing for you.
Note that you can optionally override the raw SQL that LINQ to SQL executes in cases where you want to
change it - although in 98% of scenarios I think you'll find that the SQL code that LINQ to SQL executes is
really, really good.
Databinding LINQ to SQL Queries to ASP.NET Controls
LINQ queries return results that implement the IEnumerable interface - which is also an interface that
ASP.NET server controls support to databind object. What this means is that you can databind the results
of any LINQ, LINQ to SQL, or LINQ to XML query to any ASP.NET control.
For example, we could declare an <asp:gridview>control in a .aspx page like so:

I could then databind the result of the LINQ to SQL query we wrote before to the GridView like so:

Page 5of 33 LINQ to SQL (Part 3 - Querying our Database) - ScottGu's Blog
2008/09/18 file://N:\Programming\KB\Programming\linq-to-sql-part-3-querying-our-database.as...
This will then generate a page that looks like below:
Shaping our Query Results
Right now when we are evaluating our product query, we are retrieving by default all of the column data
needed to populate the Product entity classes.
For example, this query to retrieve products:

Results in all of this data being returned:
Page 6of 33 LINQ to SQL (Part 3 - Querying our Database) - ScottGu's Blog
2008/09/18 file://N:\Programming\KB\Programming\linq-to-sql-part-3-querying-our-database.as...
Often we only want to return a subset of the data about each product. We can use the new data shaping
features that LINQ and the new C#and VB compilers support to indicate that we only want a subset of the
data by modifying our LINQ to SQL query like so:

This will result in only this data subset being returned from our database (as seen via our debug
visualizer):
Page 7of 33 LINQ to SQL (Part 3 - Querying our Database) - ScottGu's Blog
2008/09/18 file://N:\Programming\KB\Programming\linq-to-sql-part-3-querying-our-database.as...

What is cool about LINQ to SQL is that I can take full advantage of my data model class
associations when shaping my data. This enables me to express really useful (and very efficient) data
queries. For example, the below query retrieves the ID and Name from the Product entity, the total
number of orders that have been made for the Product, and then sums up the total revenue value of each
of the Product's orders:
The expression to the right of the "Revenue" property above is an example of using the "Sum" extension
method provided by LINQ. It takes a Lambda expression that returns the value of each product order item
as an argument.
LINQ to SQL is smart and is able to convert the above LINQ expression to the below SQL when it is
evaluated (as seen via our debug visualizer):
Page 8of 33 LINQ to SQL (Part 3 - Querying our Database) - ScottGu's Blog
2008/09/18 file://N:\Programming\KB\Programming\linq-to-sql-part-3-querying-our-database.as...

The above SQL causes all of the NumOrders and Revenue value computations to be done inside the SQL
server, and results in only the below data being retrieved from the database (making it really fast):

We can then databind the result sequence against our GridView control to generate pretty UI:
Page 9of 33 LINQ to SQL (Part 3 - Querying our Database) - ScottGu's Blog
2008/09/18 file://N:\Programming\KB\Programming\linq-to-sql-part-3-querying-our-database.as...
BTW - in case you were wondering, you do get full intellisense within VS 2008 when writing these types of
LINQ shaping queries:
Page 10of 33 LINQ to SQL (Part 3 - Querying our Database) - ScottGu's Blog
2008/09/18 file://N:\Programming\KB\Programming\linq-to-sql-part-3-querying-our-database.as...
In the example above I'm declaring an anonymous type that uses object initialization to shape and define
the result structure. What is really cool is that VS 2008 provides full intellisense, compilation checking,
and refactoring support when working against these anonymous result sequences as well:

Paging our Query Results
Page 11of 33 LINQ to SQL (Part 3 - Querying our Database) - ScottGu's Blog
2008/09/18 file://N:\Programming\KB\Programming\linq-to-sql-part-3-querying-our-database.as...
One of the common needs in web scenarios is to be able to efficiently build data paging UI. LINQ provides
built-in support for two extension methods that make this both easy and efficient - the Skip() and Take()
methods.
We can use the Skip() and Take() methods below to indicate that we only want to return 10 product
objects - starting at an initial product row that we specify as a parameter argument:
Note above how I did not add the Skip() and Take() operator on the initial products query declaration - but
instead added it later to the query (when binding it to my GridView datasource). People often ask me "but
doesn't this mean that the query first grabs all the data from the database and then does the paging in the
middle tier (which is bad)?" No. The reason is that LINQ uses a deferred execution model - which means
that the query doesn't actually execute until you try and iterate over the results.
One of the benefits of this deferred execution model is that it enables you to nicely compose queries
across multiple code statements (which improves code readability). It also enables you to compose
queries out of other queries - which enables some very flexible query composition and re-use scenarios.
Once I have the BindProduct() method defined above, I can write the code below in my page to retrieve
the starting index from the querystring and cause the products to be paged and displayed in the gridview:

This will then give us a products page, filtered to list only those products with more than 5 orders, showing
dynamically computed product data, and which is pageable via a querystring argument:
Page 12of 33 LINQ to SQL (Part 3 - Querying our Database) - ScottGu's Blog
2008/09/18 file://N:\Programming\KB\Programming\linq-to-sql-part-3-querying-our-database.as...
Note: When working against SQL 2005, LINQ to SQL will use the ROW_NUMBER() SQL function to
perform all of the data paging logic in the database. This ensures that only the 10 rows of data we want in
the current page view are returned from the database when we execute the above code:
Page 13of 33 LINQ to SQL (Part 3 - Querying our Database) - ScottGu's Blog
2008/09/18 file://N:\Programming\KB\Programming\linq-to-sql-part-3-querying-our-database.as...

This makes it efficient and easy to page over large data sequences.
Summary
Hopefully the above walkthrough provides a good overview of some of the cool data query opportunities
that LINQ to SQL provides. To learn more about LINQ expressions and the new language syntax
supported by the C#and VB compilers with VS 2008, please read these earlier posts of mine:
Automatic Properties, Object Initializer and Collection Initializers
Extension Methods
Lambda Expressions
Query Syntax
Anonymous Types
In my next post in this LINQ to SQL series I'll cover how we can cleanly add validation logic to our data
model classes, and demonstrate how we can use it to encapsulate business logic that executes every time
we update, insert, or delete our data. I'll then cover more advanced lazy and eager loading query
scenarios, how to use the new <asp:LINQDataSource>control to support declarative databinding of
ASP.NET controls, optimistic concurrency error resolution, and more.
Hope this helps,
Scott
Published Friday, J une 29, 2007 1:11 AM by ScottGu
Filed under: ASP.NET, Visual Studio, .NET, LINQ, Data
Comments
# re: LINQ to SQL (Part 3 - Querying our Database)
Friday, J une 29, 2007 5:13 AM by elixir
I love how you combined functional programming, query language and normal imperative programming into the
whole language model and do so elegantly
now, even subsonic won't be neccessary :)
Page 14of 33 LINQ to SQL (Part 3 - Querying our Database) - ScottGu's Blog
2008/09/18 file://N:\Programming\KB\Programming\linq-to-sql-part-3-querying-our-database.as...
LINQ to SQL (Part 4 - Updating our Database)
Over the last few weeks I've been writing a series of blog posts that cover LINQ to SQL. LINQ to SQL is a
built-in O/RM (object relational mapper) that ships in the .NET Framework 3.5 release, and which enables
you to easily model relational databases using .NET classes. You can use LINQ expressions to query the
database with them, as well as update/insert/delete data.
Below are the first three parts of my LINQ to SQL series:
Part 1: Introduction to LINQ to SQL
Part 2: Defining our Data Model Classes
Part 3: Querying our Database
In today's blog post I'll cover how we we can use the data model we created earlier, and use it to update,
insert, and delete data. I'll also show how we can cleanly integrate business rules and custom validation
logic with our data model.
Northwind Database Modeled using LINQ to SQL
In Part 2 of this series I walked through how to create a LINQ to SQL class model using the LINQ to SQL
designer that is built-into VS 2008. Below is a class model created for the Northwind sample database
and which I'll be using in this blog post:
Page 1of 45
LINQtoSQL (Part 4- Updatingour Database) - ScottGu'sBlog
2008/09/18
file://N:\Programming\KB\Programming\linq- to- sql- part- 4- updating- our- database...
When we designed our data model using the LINQ to SQL data designer above we defined five data
model classes: Product, Category, Customer, 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.
When we defined our data model, the LINQ to SQL designer also created a custom DataContext class that
provides the main conduit by which we'll query our database and apply updates/changes. In the example
data model we defined above this class was named "NorthwindDataContext". The NorthwindDataContext
class has properties that represent each Table we modeled within the database (specifically: Products,
Categories, Customers, Orders, OrderDetails).
As I covered in Part 3 of this blog series, we can easily use LINQ syntax expressions to query and retrieve
data from our database using this NorthwindDataContext class. LINQ to SQL will then automatically
translate these LINQ query expressions to the appropriate SQL code to execute at runtime.
Page 2of 45 LINQ to SQL (Part 4 - Updating our Database) - ScottGu's Blog
2008/09/18 file://N:\Programming\KB\Programming\linq-to-sql-part-4-updating-our-database.asp...
For example, I could write the below LINQ expression to retrieve a single Product object by searching on
the Product name:
I could then write the LINQ query expression below to retrieve all products from the database that haven't
yet had an order placed for them, and which also cost more than $100:
Note above how I am using the "OrderDetails" association for each product as part of the query to only
retrieve those products that have not had any orders placed for them.
Change Tracking and DataContext.SubmitChanges()
When we perform queries and retrieve objects like the product instances above, LINQ to SQL will by
default keep track of any changes or updates we later make to these objects. We can make any number
of queries and changes we want using a LINQ to SQL DataContext, and these changes will all be tracked
together.
Note: LINQ to SQL change tracking happens on the consuming caller side - and not in the
database. This means that you are not consuming any database resources when using it,
nor do you need to change/install anything in the database to enable it.
After making the changes we want to the objects we've retrieved from LINQ to SQL, we can then
optionally call the "SubmitChanges()" method on our DataContext to apply the changes back to the
database. This will cause LINQ to SQL to dynamically calculate and execute the appropriate SQL code to
update the database.
For example, I could write the below code to update the price and #of units in stock of the "Chai" product
in the database:
Page 3of 45 LINQ to SQL (Part 4 - Updating our Database) - ScottGu's Blog
2008/09/18 file://N:\Programming\KB\Programming\linq-to-sql-part-4-updating-our-database.asp...
When I call northwind.SubmitChanges() above, LINQ to SQL will dynamically construct and execute a
SQL "UPDATE" statement that will update the two product property values we modified above.
I could then write the below code to loop over unpopular, expensive products and set the "ReorderLevel"
property of them to zero:
When I call northwind.SubmitChanges() above, LINQ to SQL will calculate and execute an appropriate set
of UPDATE statements to modify the products who had their ReorderLevel property changed.
Note that if a Product's property values weren't changed by the property assignments above, then the
object would not be considered changed and LINQ to SQL would therefore not execute an update for that
product back to the database. For example - if the "Chai" product's unitprice was already $2 and the
number of units in stock was 4, then calling SubmitChanges() would not cause any database update
statements to execute. Likewise, only those products in the second example whose ReorderLevel was not
already 0 would be updated when the SubmitChanges() method was called.
Insert and Delete Examples
In addition to updating existing rows in the database, LINQ to SQL obviously also enables you to insert
and delete data. You can accomplish this by adding/removing data objects from the DataContext's table
collections, and by then calling the SubmitChanges() method. LINQ to SQL will keep track of these
additions/removals, and automatically execute the appropriate SQL INSERT or DELETE statements when
SubmitChanges() is invoked.
Inserting a New Product
I can add a new product to my database by creating a new "Product" class instance, setting its properties,
and then by adding it to my DataContext's "Products" collection:
Page 4of 45 LINQ to SQL (Part 4 - Updating our Database) - ScottGu's Blog
2008/09/18 file://N:\Programming\KB\Programming\linq-to-sql-part-4-updating-our-database.asp...
When we call "SubmitChanges()" above a new row will be created in our products table.
Deleting Products
J ust as I can express that I want to add a new Product to the database by adding a Product object into the
DataContext's Products collection, I can likewise express that I want to delete a product from a database
by removing it from the DataContext's Products collection:
Note above how I'm retrieving a sequence of discontinued products that no one has ever ordered using a
LINQ query, and then passing it to the RemoveAll() method on my DataContext's "Products" collection.
When we call "SubmitChanges()" above all of these Product rows will be deleted from our products table.
Updates across Relationships
What makes O/R mappers like LINQ to SQL extremely flexible is that they enable us to easily model
cross-table relationships across our data model. For example, I can model each Product to be in a
Category, each Order to contain OrderDetails for line-items, associate each OrderDetail line-item with a
Product, and have each Customer contain an associated set of Orders. I covered how to construct and
model these relationships in Part 2 of this blog series.
LINQ to SQL enables me to take advantage of these relationships for both querying and updating my data.
For example, I could write the below code to create a new Product and associate it with an existing
"Beverages" category in my database like so:
Page 5of 45 LINQ to SQL (Part 4 - Updating our Database) - ScottGu's Blog
2008/09/18 file://N:\Programming\KB\Programming\linq-to-sql-part-4-updating-our-database.asp...
Note above how I'm adding the Product object into the Category's Products collection. This will indicate
that there is a relationship between the two objects, and cause LINQ to SQL to automatically maintain the
foreign-key/primary key relationship between the two when I call "SubmitChanges()".
For another example of how LINQ to SQL can help manage cross-table relationships for us and help clean
up our code, let's look at an example below where I'm creating a new Order for an existing customer.
After setting the required ship date and freight costs for the order, I then create two order line-item objects
that point to the products the customer is ordering. I then associate the order with the customer, and
update the database with all of the changes.
Page 6of 45 LINQ to SQL (Part 4 - Updating our Database) - ScottGu's Blog
2008/09/18 file://N:\Programming\KB\Programming\linq-to-sql-part-4-updating-our-database.asp...
As you can see, the programming model for performing all of this work is extremely clean and object
oriented.
Transactions
A transaction is a service provided by a database (or other resource manager) to guarantee that a series
of individual actions occur atomically - meaning either they all succeed or they all don't, and if they don't
then they are all automatically undone before anything else is allowed to happen.
When you call SubmitChanges() on your DataContext, the updates will always be wrapped in a
Transaction. This means that your database will never be in an inconsistent state if you perform multiple
changes - either all of the changes you've made on your DataContext are saved, or none of them are.
If no transaction is already in scope, the LINQ to SQL DataContext object will automatically start a
database transaction to guard updates when you call SubmitChanges(). Alternatively, LINQ to SQL also
enables you to explicitly define and use your own TransactionScope object (a feature introduced in .NET
2.0). This makes it easier to integrate LINQ to SQL code with existing data access code you already
have. It also means that you can enlist non-database resources into the transaction - for example: you
could send off a MSMQ message, update the file-system (using the new transactional file-system support),
etc - and scope all of these work items in the same transaction that you use to update your database with
LINQ to SQL.
Page 7of 45 LINQ to SQL (Part 4 - Updating our Database) - ScottGu's Blog
2008/09/18 file://N:\Programming\KB\Programming\linq-to-sql-part-4-updating-our-database.asp...
Validation and Business Logic
One of the important things developers need to think about when working with data is how to incorporate
validation and business rule logic. Thankfully LINQ to SQL supports a variety of ways for developers to
cleanly integrate this with their data models.
LINQ to SQL enables you to add this validation logic once - and then have it be honored regardless of
where/how the data model you've created is used. This avoids you having to repeat logic in multiple
places, and leads to a much more maintainable and clean data model.
Schema Validation Support
When you define your data model classes using the LINQ to SQL designer in VS 2008, they will by default
be annotated with some validation rules inferred from the schema of the tables in the database.
The datatypes of the properties in the data model classes will match the datatypes of the database
schema. This means you will get compile errors if you attempt to assign a boolean to a decimal value, or if
you attempt to implicitly convert numeric types incorrectly.
If a column in the database is marked as being nullable, then the corresponding property in the data model
class created by the LINQ to SQL designer will be a nullable type. Columns not marked as nullable will
automatically raise exceptions if you attempt to persist an instance with a null value. LINQ to SQL will
likewise ensure that identity/unique column values in the database are correctly honored.
You can obviously use the LINQ to SQL designer to override these default schema driven validation
settings if you want - but by default you get them automatically and don't have to take any additional steps
to enable them. LINQ to SQL also automatically handles escaping SQL values for you - so you don't need
to worry about SQL injection attacks when using it.
Custom Property Validation Support
Schema driven datatype validation is useful as a first step, but usually isn't enough for real-world
scenarios.
Consider for example a scenario with our Northwind database where we have a "Phone" property on the
"Customer" class which is defined in the database as an nvarchar. Developers using LINQ to SQL could
write code like below to update it using a valid telephone number:
The challenge that we will run into with our application, however, is that the below code is also legal from a
pure SQL schema perspective (because it is still a string even though it is not a valid phone number):
To prevent bogus phone numbers from being added into our database, we can add a custom property
validation rule to our Customer data model class. Adding a rule to validate phone numbers using this
Page 8of 45 LINQ to SQL (Part 4 - Updating our Database) - ScottGu's Blog
2008/09/18 file://N:\Programming\KB\Programming\linq-to-sql-part-4-updating-our-database.asp...
feature is really easy. All we need to-do is to add a new partial class to our project that defines the method
below:
The code above takes advantage of two characteristics of LINQ to SQL:
1) All classes created by the LINQ to SQL designer are declared as "partial" classes - which means that
developers can easily add additional methods, properties, and events to them (and have them live in
separate files). This makes it very easy to augment the data model classes and DataContext classes
created by the LINQ to SQL designer with validation rules and additional custom helper methods that you
define. No configuration or code wire-up is required.
2) LINQ to SQL exposes a number of custom extensibility points in its data model and DataContext
classes that you can use to add validation logic before and after things take place. Many of these
extensibility points utilize a new language feature called "partial methods" that is being introduced with VB
and C#in VS 2008 Beta2. Wes Dyer from the C#team has a good explanation of how partial methods
works in this blog post here.
In my validation example above, I'm using the OnPhoneChanging partial method that is executed anytime
someone programmatically sets the "Phone" property on a Customer object. I can use this method to
validate the input however I want (in this case I'm using a regular expression). If everything passes
successfully, I just return from the method and LINQ to SQL will assume that the value is valid. If there
are any issues with the value, I can raise an exception within the validation method - which will prevent the
assignment from taking place.
Custom Entity Object Validation Support
Property level validation as used in the scenario above is very useful for validating individual properties on
a data model class. Sometimes, though, you want/need to validate multiple property values on an object
against each other.
Consider for example a scenario with an Order object where you set both the "OrderDate" and the
"RequiredDate" properties:
Page 9of 45 LINQ to SQL (Part 4 - Updating our Database) - ScottGu's Blog
2008/09/18 file://N:\Programming\KB\Programming\linq-to-sql-part-4-updating-our-database.asp...
The above code is legal from a pure SQL database perspective - even though it makes absolutely no
sense for the required delivery date of the new order to be entered as yesterday.
The good news is that LINQ to SQL in Beta2 makes it easy for us to add custom entity level validation
rules to guard against mistakes like this from happening. We can add a partial class for our "Order" entity
and implement the OnValidate() partial method that will be invoked prior to the entity's values being
persisted into the database. Within this validation method we can then access and validate all of the data
model class properties:
Within this validation method I can check any of the entity's property values (and even obtain read-only
access to its associated objects), and raise an exception as needed if the values are incorrect. Any
exceptions raised from the OnValidate() method will abort any changes from being persisted in the
database, and rollback all other changes in the transaction.
Custom Entity Insert/Update/Delete Method Validation
There are times when you want to add validation logic that is specific to insert, update or delete scenarios.
LINQ to SQL in Beta2 enables this by allowing you to add a partial class to extend your DataContext class
and then implement partial methods to customize the Insert, Update and Delete logic for your data model
entities. These methods will be called automatically when you invoke SubmitChanges() on your
DataContext.
You can add appropriate validation logic within these methods - and if it passes then tell LINQ to SQL to
continue with persisting the relevant changes to the database (by calling the DataContext's
"ExecuteDynamicXYZ" method):
Page 10of 45 LINQ to SQL (Part 4 - Updating our Database) - ScottGu's Blog
2008/09/18 file://N:\Programming\KB\Programming\linq-to-sql-part-4-updating-our-database.asp...
What is nice about adding the above methods is that the appropriate ones are automatically invoked
regardless of the scenario logic that caused the data objects to be created/updated/deleted. For example,
consider a simple scenario where we create a new Order and associate it with an existing Customer:
When we call northwind.SubmitChanges() above, LINQ to SQL will determine that it needs to persist a
new Order object, and our "InsertOrder" partial method will automatically be invoked.
Page 11of 45 LINQ to SQL (Part 4 - Updating our Database) - ScottGu's Blog
2008/09/18 file://N:\Programming\KB\Programming\linq-to-sql-part-4-updating-our-database.asp...
Advanced: Looking at the Entire Change List for the Transaction
There are times when adding validation logic can't be done purely by looking at individual
insert/update/delete operations - and instead you want to be able to look at the entire change list of
operations that are occurring for a transaction.
Starting with Beta2 of .NET 3.5, LINQ to SQL now enables you to get access to this change list by calling
the public DataContext.GetChangeList() method. This will return back a ChangeList object that exposes
collections of each addition, removal and modification that has been made.
One approach you can optionally employ for advanced scenarios is to sub-class the DataContext class
and override its SubmitChange() method. You can then retrieve the ChangeList() for the update operation
and perform any custom validation you want prior to executing it:

The above scenario is a somewhat advanced one - but it is nice to know that you always have the ability to
drop-down and take advantage of it if needed.
Handling Simultaneous Changes with Optimistic Concurrency
One of the things that developers need to think about in multi-user database systems is how to handle
simultaneous updates of the same data in the database. For example, assume two users retrieve a
product object within an application, and one of the users changes the ReorderLevel to 0 while the other
changes it to 1. If both users then attempt to save the product back to the database, the developer needs
to decide how to handle the change conflicts.
One approach is to just "let the last writer win" - which means that the first user's submitted value will be
lost without the end-users realizing it. This is usually considered a poor (and incorrect) application
experience.
Another approach which LINQ to SQL supports is to use an optimistic concurrency model - where LINQ to
SQL will automatically detect if the original values in the database have been updated by someone else
prior to the new values being persisted. LINQ to SQL can then provide a conflict list of changed values to
the developer and enable them to either reconcile the differences or provide the end-user of the
application with UI to indicate what they want to-do.
I'll cover how to use optimistic concurrency with LINQ to SQL in a future blog post.
Page 12of 45 LINQ to SQL (Part 4 - Updating our Database) - ScottGu's Blog
2008/09/18 file://N:\Programming\KB\Programming\linq-to-sql-part-4-updating-our-database.asp...
Using SPROCs or Custom SQL Logic for Insert/Update/Delete Scenarios
One of the questions that developers (and especially DBAs) who are used to writing SPROCs with custom
SQL usually ask when seeing LINQ to SQL for the first time is - "but how can I have complete control of
the underlying SQL that is executed?"
The good news is that LINQ to SQL has a pretty flexible model that enables developers to override the
dynamic SQL that is automatically executed by LINQ to SQL, and instead call custom insert, update,
delete SPROCs that they (or a DBA) define themselves.
What is really nice is that you can start off by defining your data model and have LINQ to SQL
automatically handle the insert, update, delete SQL logic for you. You can then at a later point customize
the data model to use your own custom SPROCs or SQL for updates - without having to change any of the
application logic that is using your data model, nor would you have to change any of the validation or
business rules logic supporting it (all of this stays the same). This provides a lot of flexibility in how you
build your application.
I'll cover how to customize your data models to use SPROCs or custom SQL in a future blog post.
Summary
Hopefully the above post provides a good summary of how you can easily use LINQ to SQL to update
your database, and cleanly integrate validation and business logic with your data models. I think you'll find
that LINQ to SQL can dramatically improve your productivity when working with data, and enable you to
write extremely clean object-oriented data access code.
In upcoming blog posts in this series I'll cover the new <asp:linqdatasource>control coming in .NET 3.5,
and talk about how you can easily build data UI in ASP.NET that takes advantage of LINQ to SQL data
models. I'll also cover some more specific LINQ to SQL programming concepts including optimistic
concurrency, lazy and eager loading, table mapping inheritance, custom SQL/SPROC usage, and more.
Hope this helps,
Scott
Published Wednesday, J uly 11, 2007 10:00 AM by ScottGu
Filed under: ASP.NET, Visual Studio, .NET, LINQ, Data, SQL Server

Comments
# re: LINQ to SQL (Part 4 - Updating our Database)
Wednesday, J uly 11, 2007 1:22 PM by rodrigo
Hi scott great articles but I don't think there is an example of how
to do a LINQ code that retrieves data from an outer join.
Could you provide a simple snippet to do that?
# re: LINQ to SQL (Part 4 - Updating our Database)
Wednesday, J uly 11, 2007 1:30 PM by Stefan J okull
Awesome article Scott.
One question. When inserting an object that has it's ID mapped to an Identity column, is the Id property on the object
automatically updated after calling SubmitChanges() or would we have to fetch the newly created object from the
datacontext?
Page 13of 45 LINQ to SQL (Part 4 - Updating our Database) - ScottGu's Blog
2008/09/18 file://N:\Programming\KB\Programming\linq-to-sql-part-4-updating-our-database.asp...
LINQ to SQL (Part 5 - Binding UI using the
ASP:LinqDataSource Control)
Over the last few weeks I've been writing a series of blog posts that cover LINQ to SQL. LINQ to SQL is a
built-in O/RM (object relational mapper) that ships in the .NET Framework 3.5 release, and which enables
you to easily model relational databases using .NET classes. You can use LINQ expressions to query the
database with them, as well as update/insert/delete data.
Below are the first four parts of my LINQ to SQL series:
Part 1: Introduction to LINQ to SQL
Part 2: Defining our Data Model Classes
Part 3: Querying our Database
Part 4: Updating our Database
In these previous LINQ to SQL blog posts I focused on how you can programmatically use LINQ to SQL to
easily query and update data within a database.
In today's blog post I'll cover the new <asp:LinqDataSource>control that is shipping as part of ASP.NET in
the upcoming .NET 3.5 release. This control is a new datasource control for ASP.NET (like the
ObjectDataSource and SQLDataSource controls that shipped with ASP.NET 2.0) which makes
declaratively binding ASP.NET UI controls to LINQ to SQL data models super easy.
Sample Application We'll be Building
The simple data editing web application I'll walkthrough building in this tutorial is a basic data
entry/manipulation front-end for products within a database:
Page 1of 59
LINQtoSQL (Part 5- BindingUI usingtheASP:LinqDataSourceControl) - ScottG...
2008/09/18
file://N:\Programming\KB\Programming\linq- to- sql- part- 5- binding- ui- using- the- ...
The application will support the following end-user features:
1. Allow users to filter the products by category
2. Allow users to sort the product listing by clicking on a column header (Name, Price, Units In Stock,
etc)
3. Allow users to skip/page over multiple product listings (10 products per page)
4. Allow users to edit and update any of the product details in-line on the page
5. Allow users to delete products from the list
The web application will be implemented with a clean object-oriented data model built using the LINQ to
SQL ORM.
All of the business rules and business validation logic will be implemented in our data model tier - and not
within the UI tier or in any of the UI pages. This will ensure that: 1) a consistent set of business rules are
used everywhere within the application, 2) we write less code and don't repeat ourselves, and 3) we can
easily modify/adapt our business rules at a later date and not have to update them in dozens of different
places across our application.
Page 2of 59 LINQ to SQL (Part 5 - Binding UI using the ASP:LinqDataSource Control) - ScottGu...
2008/09/18 file://N:\Programming\KB\Programming\linq-to-sql-part-5-binding-ui-using-the-asp-l...
We will also take advantage of the built-in paging/sorting support within LINQ to SQL to ensure that
features like the product listing paging/sorting are performed not in the middle-tier, but rather in the
database (meaning only 10 products are retrieved from the database at any given time - we are not
retrieving thousands of rows and doing the sorting/paging within the web-server).
What is the <asp:LinqDataSource> control and how does it help?
The <asp:LinqDataSource>control is an ASP.NET control that implements the DataSourceControl
pattern introduced with ASP.NET 2.0. It is similar to the ObjectDataSource and SqlDataSource controls in
that it can be used to declaratively bind other ASP.NET controls on a page to a datasource. Where it
differs is that instead of binding directly to a database (like the SqlDataSource) or to a generic class (like
the ObjectDataSource), the <asp:linqdatasource>is designed to bind against a LINQ enabled data model.
One of the benefits of using the <asp:linqdatasource>control is that it leverages the flexibility that LINQ
based ORMs provide. You don't need to define custom query/insert/update/delete methods for the
datasource to call - instead you can point the <asp:linqdatasource>control at your data model, identify
what entity table you want it to work against, and then bind any ASP.NET UI control against the
<asp:linqdatasource>and have them work with it.
For example, to get a basic product listing UI on my page that works against Product entities within a LINQ
to SQL data model, I could simply declare a <asp:linqdatasource>on my page that points to my LINQ to
SQL datacontext class, and identify the entities (for example: Products) in the LINQ to SQL data model I
want to bind against. I could then point a GridView at it (by settings its DataSourceID property) to get a
grid-like view of the Product content:
Without having to-do anything else, I can run the page and have a listing of my Product data with built-in
support for paging and sorting over the data. I can add a edit/delete button on the Grid and automatically
have update support as well. I don't need to add any methods, map any parameters, or write any code for
the <asp:LinqDataSource>to handle both these querying and updating scenarios - it can work against the
LINQ to SQL data model we point it against and do these operations automatically. When updates are
made, the LINQ to SQL ORM will automatically ensure that all business rules and validation logic we've
added (as partial methods) to the LINQ to SQL data model pass before persisting anything to the
database.
Important: The beauty of LINQ and LINQ to SQL is that it obviously isn't tied to being used
only in UI scenarios - or with particular UI binding controls like the LinqDataSource. As
you've seen in my previous posts in this series, writing code using the LINQ to SQL ORM is
extremely clean. You can always write custom UI code to directly work against your LINQ to
SQL data model if you prefer, or when you find a UI scenario that isn't particularly suited to
using the <asp:linqdatasource>.
The below sections walkthrough using LINQ to SQL and the <asp:LinqDataSource>control to build the
web application scenario I defined above.
Step 1: Define our Data Model
Page 3of 59 LINQ to SQL (Part 5 - Binding UI using the ASP:LinqDataSource Control) - ScottGu...
2008/09/18 file://N:\Programming\KB\Programming\linq-to-sql-part-5-binding-ui-using-the-asp-l...
We'll begin working on the application by first defining the data model we'll use to represent our database.
I discussed how to create a LINQ to SQL data model using VS 2008's LINQ to SQL designer in Part 2 of
this series. Below is a screenshot of the data model classes I can quickly create using the LINQ to SQL
designer to model the "Northwind" sample database:
We'll revisit our data model in Step 5 of this tutorial below when we add some business validation rules to
it. But to begin with we'll just use the above data model as-is to build our UI.
Step 2: Creating a Basic Product Listing
We'll start our UI by creating an ASP.NET page with a <asp:gridview>control on it and use some CSS to
style it:
Page 4of 59 LINQ to SQL (Part 5 - Binding UI using the ASP:LinqDataSource Control) - ScottGu...
2008/09/18 file://N:\Programming\KB\Programming\linq-to-sql-part-5-binding-ui-using-the-asp-l...
We could write code to programmatically bind our data model to the GridView (like I did in Part 3 of this
series), or alternatively I could use the new <asp:linqdatasource>control to bind the GridView to our data
model.
VS 2008 includes build-in designer support to make it easy to connect up our GridView (or any other
ASP.NET server control) to LINQ data. To bind our grid above to the data model we created earlier, we
can switch into design-view, select the GridView, and then select the "New Data Source..." option within
the "Choose Data Source:" drop-down:
This will bring up a dialog box that lists the available datasource options to create. Select the new "LINQ"
option in the dialog box and name the resulting <asp:linqdatasource>control you want to create:
Page 5of 59 LINQ to SQL (Part 5 - Binding UI using the ASP:LinqDataSource Control) - ScottGu...
2008/09/18 file://N:\Programming\KB\Programming\linq-to-sql-part-5-binding-ui-using-the-asp-l...
The <asp:linqdatasource>designer will then display the available LINQ to SQL DataContext classes that
your application can use (including those in class libraries that you are referencing):
Page 6of 59 LINQ to SQL (Part 5 - Binding UI using the ASP:LinqDataSource Control) - ScottGu...
2008/09/18 file://N:\Programming\KB\Programming\linq-to-sql-part-5-binding-ui-using-the-asp-l...
We'll want to select the data model we created with the LINQ to SQL designer earlier. We'll then want to
select the table within our data model that we want to be the primary entity for the <asp:linqdatasource>to
bind against. For this scenario we'll want to select the "Products" entity class we built. We'll also want to
select the "Advanced" button and enable updates and deletes for the datasource:
Page 7of 59 LINQ to SQL (Part 5 - Binding UI using the ASP:LinqDataSource Control) - ScottGu...
2008/09/18 file://N:\Programming\KB\Programming\linq-to-sql-part-5-binding-ui-using-the-asp-l...
When we click the "Finish" button above, VS 2008 will declare a <asp:linqdatasource>within our .aspx
page, and update the <asp:gridview>to point to it (via its DataSourceID property). It will also
automatically provide column declarations in the Grid based on the schema of the Product entity we
choose to bind against:
We can then pull up the "smart task" context UI of the GridView and indicate that we want to enable
paging, sorting, editing and deleting on it:
Page 8of 59 LINQ to SQL (Part 5 - Binding UI using the ASP:LinqDataSource Control) - ScottGu...
2008/09/18 file://N:\Programming\KB\Programming\linq-to-sql-part-5-binding-ui-using-the-asp-l...

We can then press F5 to run our application, and have a product listing page with full paging and sorting
support (note the paging indexes at the bottom of the grid below):
Page 9of 59 LINQ to SQL (Part 5 - Binding UI using the ASP:LinqDataSource Control) - ScottGu...
2008/09/18 file://N:\Programming\KB\Programming\linq-to-sql-part-5-binding-ui-using-the-asp-l...
We can also select the "edit" or "delete" button on each row to update the data:

If we flip into source view on the page, we'll see that the markup of the page contains the content below.
The <asp:linqdatasource>control points at the LINQ to SQL DataContext we created earlier, as well as
the entity table we want to bind against. The GridView then points at the <asp:linqdatasource>control (via
Page 10of 59 LINQ to SQL (Part 5 - Binding UI using the ASP:LinqDataSource Control) - Scott...
2008/09/18 file://N:\Programming\KB\Programming\linq-to-sql-part-5-binding-ui-using-the-asp-l...
its DataSourceID) and indicates which columns should be included in the grid, what their header text
should be, as well as what sort expression to use when the column header is selected.
Now that we have the basics of our web UI working against our LINQ to SQL data-model, we can go
ahead and further customize the UI and behavior.
Step 3: Cleaning up our Columns
Our GridView above has a lot of columns defined within it, and two of the column values (the SupplierID
and the CategoryID) are currently foreign-key numbers -- which certainly isn't the ideal way to represent
them to an end-user.
Removing Unnecessary Columns
We can start cleaning up our UI by deleting a few of the columns we don't need. I can do this in source
mode (simply nuke the <asp:boundfield>declarations) or in designer mode (just click on the column in the
designer and choose the "Remove" task). For example, we could remove the "QuantityPerUnit" column
below and re-run our application to get this slightly cleaner UI:
Page 11of 59 LINQ to SQL (Part 5 - Binding UI using the ASP:LinqDataSource Control) - Scott...
2008/09/18 file://N:\Programming\KB\Programming\linq-to-sql-part-5-binding-ui-using-the-asp-l...
If you have used the <asp:ObjectDataSource>control before and explicitly passed update parameters to
update methods (the default when using DataSet based TableAdapters) one of the things you know can
be painful is that you have to change the method signatures of your TableAdapter's update methods when
the parameters based by your UI are modified. For example: if we deleted a column in our grid (like
above), we'd end up having to modify our TableAdapter to support update methods without that
parameter.
One of the really nice things about the <asp:LinqDataSource>control is that you do not need to-do these
types of changes. Simply delete (or add) a column from your UI and re-run the application - no other
changes are required. This makes changing web UI built using the <asp:LinqDataSource>much easier,
and enables much faster scenarios iterations within an application.
Cleaning up the SupplierID and CategoryID Columns
Currently we are displaying the foreign-key integer values in our GridView for the Supplier and Category of
each Product:
While accurate from a data model perspective, it isn't very end-user friendly. What I really want to-do is to
display the CategoryName and SupplierName instead, and provide a drop-downlist while in Edit mode to
enable end-users to easily associate the SupplierID and CategoryID values.
I can change the GridView to display the Supplier Name and Category Name instead of the ID's by
replacing the default <asp:BoundField>in our GridView with an <asp:TemplateField>. Within this
Page 12of 59 LINQ to SQL (Part 5 - Binding UI using the ASP:LinqDataSource Control) - Scott...
2008/09/18 file://N:\Programming\KB\Programming\linq-to-sql-part-5-binding-ui-using-the-asp-l...
TemplateField I can add any content I want to customize the look of the column.
In the source code below I'm going to take advantage of the fact that each Product class in the LINQ to
SQL data model we created has a Supplier and Category property on it. What this means is that I can
easily databind their Supplier.CompanyName and Category.CategoryName sub-properties within our Grid:

And now when I run the application I get the human readable Category and Supplier name values instead:
Page 13of 59 LINQ to SQL (Part 5 - Binding UI using the ASP:LinqDataSource Control) - Scott...
2008/09/18 file://N:\Programming\KB\Programming\linq-to-sql-part-5-binding-ui-using-the-asp-l...
To get drop-down list UI for the Supplier and Category columns while in Edit-Mode in the Grid, I will
first add two additional <asp:LinqDataSource>controls to my page. I will configure these to bind against
the Categories and Suppliers within the LINQ to SQL data model we created earlier:
I can then go back to the <asp:TemplateField>columns we added to our GridView earlier and customize
their edit appearance (by specifying an EditItemTemplate). We'll customize each column to have a
dropdownlist control when in edit mode, where the available values in the dropdownlists are pulled from
the categories and suppliers datasource controls above, and where we two-way databind the selected
value to the Product's SupplierID and CategoryID foreign keys:
Page 14of 59 LINQ to SQL (Part 5 - Binding UI using the ASP:LinqDataSource Control) - Scott...
2008/09/18 file://N:\Programming\KB\Programming\linq-to-sql-part-5-binding-ui-using-the-asp-l...
And now when end-users click edit in the GridView, they are presented a drop-down list of all valid
Supplier's to associate the product with:
And when they hit save the Product is updated appropriately (the GridView will use the DropDownList's
currently selected value to bind the SupplierID).
Step 4: Filtering our Product Listing
Rather than show all products within the database, we can update our UI to include a dropdownlist that
allows the user to filter the products by a particular category.
Because we already added a <asp:LinqDataSource>control to the page earlier that references our
Categories within our LINQ to SQL data model, all I need to-do to create a drop-downlist control at the top
of the page that binds against this. For example:
Page 15of 59 LINQ to SQL (Part 5 - Binding UI using the ASP:LinqDataSource Control) - Scott...
2008/09/18 file://N:\Programming\KB\Programming\linq-to-sql-part-5-binding-ui-using-the-asp-l...

When I run the page I'll now get a filter dropdownlist of all categories at the top of the page:

My last step is to configure the GridView to only show those Products in the category the end-user selects
from the dropdownlist. The easiest way to-do this is by selecting the "Configure DataSource" option in the
GridView smart task:

This will bring me back to the <asp:LinqDataSource>control's design-time UI that we used at the very
beginning of this tutorial. I can select the "Where" button within this to add a binding filter to the
datasource control. I can add any number of filter expressions, and declaratively pull the values to filter by
from a variety of places (for example: from the querystring, from form-values, from other controls on the
page, etc):
Page 16of 59 LINQ to SQL (Part 5 - Binding UI using the ASP:LinqDataSource Control) - Scott...
2008/09/18 file://N:\Programming\KB\Programming\linq-to-sql-part-5-binding-ui-using-the-asp-l...
Above I'm going to choose to filter by the Products by their CategoryID value, and then retrieve this
CategoryID from the DropDownList control we just created on our page:
Page 17of 59 LINQ to SQL (Part 5 - Binding UI using the ASP:LinqDataSource Control) - Scott...
2008/09/18 file://N:\Programming\KB\Programming\linq-to-sql-part-5-binding-ui-using-the-asp-l...
When we hit finish, the <asp:linqdatasource>control in our page will have been updated to reflect this filter
clause like so:
And when we now run the page the end-user will now be able to select from the available Categories in
the filter drop-downlist and page, sort, edit and delete just the products in that category:
Page 18of 59 LINQ to SQL (Part 5 - Binding UI using the ASP:LinqDataSource Control) - Scott...
2008/09/18 file://N:\Programming\KB\Programming\linq-to-sql-part-5-binding-ui-using-the-asp-l...
The <asp:LinqDataSource>control will automatically apply the appropriate LINQ filter expression when
working against our LINQ to SQL data model classes to ensure that only the required data is retrieved
from the database (for example: in the Grid above only the 3 rows of Product data from the second page
of Confection products will be retrieved from the database).
You can optionally handle the Selecting event on the <asp:LinqDataSource>if you want to write a custom
LINQ expression in code to completely customize the query instead.
Step 5: Adding Business Validation Rules
As I discussed in Part 4 of this LINQ to SQL series, when we define LINQ to SQL data models we will
automatically have a default set of schema based validation constraints added to our data model classes.
This means that if I try and enter a null value for a required column, try and assign a string to an integer, or
assign a foreign-key value to a row that doesn't exist, our LINQ to SQL data model will raise an error and
ensure that our database integrity is maintained.
Basic schema validation is only a first step, though, and is rarely enough for most real-world applications.
Typically we'll want/need to add additional business rules and application-level validation to our data
model classes. Thankfully LINQ to SQL makes adding these types of business validation rules easy (for
details on the various validation approaches available, please read Part 4 of my LINQ to SQL series).
Example Business Validation Rule Scenario
For example, let's consider a basic business logic rule we might want to enforce. Specifically, we want to
ensure that a user of our application can't discontinue a product while we still have units on backorder for
it:

Page 19of 59 LINQ to SQL (Part 5 - Binding UI using the ASP:LinqDataSource Control) - Scott...
2008/09/18 file://N:\Programming\KB\Programming\linq-to-sql-part-5-binding-ui-using-the-asp-l...
If a user tries to save the above row, we'll want to prevent this change from being persisted and throw an
appropriate error telling the user how to fix it.
Adding a Data Model Validation Rule
The wrong place to add this type of business validation rule is in the UI layer of our application. Adding it
in the UI layer of our application will mean that the rule will be specific to only that one place, and will not
be automatically enforced when we add another page to our application that also updates Products.
Distributing business rules/logic in our UI layer will also make life extremely painful as our application
grows in size - since changes/updates to our business will necessitate making code changes all over the
place.
The right place to specify this type of business logic validation is instead in our LINQ to SQL data model
classes that we defined earlier. As I discussed in Part 4 of this series, all classes generated by the LINQ
to SQL designer are defined as "partial" classes - which means that we can easily add additional
methods/events/properties to them. The LINQ to SQL data model classes automatically call validation
methods that we can implement to enforce custom validation logic within them.
For example, I could add a partial Product class to my project that implements the OnValidate() partial
method that LINQ to SQL calls prior to persisting a Product entity. Within this OnValidate() method I could
add the following business rule to enforce that products can't have a Reorder Level if the product is
discontinued:
Once I add the above class into my LINQ to SQL project, the above business rule will be enforced anytime
anyone uses my data model to try and modify the database. This is true for both updating existing
Products, as well as adding new Products into the database.
Because the <asp:LinqDataSource>that we defined in our pages above works against our LINQ to SQL
data model classes, all of its update/insert/delete logic will now have to pass the above validation check
prior to the change being persisted. We do not need to-do anything to our UI tier in order for this validation
to occur - it will automatically be applied anywhere and everywhere our LINQ to SQL data model is used.
Adding Nice Error Handling in our UI Tier
By default if a user now uses our GridView UI to enter a non-valid UnitsOnOrder/Discontinued
combination, our LINQ to SQL data model classes will raise an exception. The <asp:LinqDataSource>will
in turn catch this error and provides an event that users can use to handle it. If no one handles the event
then the GridView (or other) control bound to the <asp:LinqDataSource>will catch the error and provide
an event for users to handle it. If no one handles the error there then it will be passed up to the Page to
handle, and if not there to the global Application_Error() event handler in the Global.asax file. Developers
can choose any place along this path to insert appropriate error handling logic to provide the right end-
user experience.
For the application we defined above, probably the best place to handle any update errors is by handling
the RowUpdated event on our GridView. This event will get fired every time an update is attempted on our
datasource, and we can access the exception error details if the update event fails. We can add the below
code to check if an error occurs, and if so display an appropriate error message to the end-user:
Page 20of 59 LINQ to SQL (Part 5 - Binding UI using the ASP:LinqDataSource Control) - Scott...
2008/09/18 file://N:\Programming\KB\Programming\linq-to-sql-part-5-binding-ui-using-the-asp-l...
Notice above how we have not added any validation specific logic into our UI. Instead, I am retrieving the
validation error message string we raised in our business logic and am using it to display an appropriate
message to the end-user (I am then displaying a more generic error message in the event of other
failures).
Notice how I'm also indicating above that I want the GridView to stay in Edit mode when an error occurs -
that way the user can avoid losing their changes, and can modify the values they entered and click
"update" again to try and save them. We can then add a <asp:literal>control with the "ErrorMessage"
ID anywhere we want on our page to control where where we want the error message to be displayed:

And now when we try and update the Product with an invalid value combination we'll see an error
message indicating how to fix it:
Page 21of 59 LINQ to SQL (Part 5 - Binding UI using the ASP:LinqDataSource Control) - Scott...
2008/09/18 file://N:\Programming\KB\Programming\linq-to-sql-part-5-binding-ui-using-the-asp-l...
The nice thing about using this approach is that I can now add or change my data model's business rules
and not have to modify any of my UI tier's code to have them pick up and honor the changes. The
validation rules, and corresponding error messages, can be written and centralized in one place in my data
model and automatically applied everywhere.
Summary
The <asp:LinqDataSource>control provides an easy way to bind any ASP.NET UI control to a LINQ to
SQL data model. It enables UI controls to both retrieve data from a LINQ to SQL data model, as well as
cleanly apply updates/inserts/deletes to it.
In our application above we used the LINQ to SQL ORM designer to create a clean, object oriented data
model. We then added three ASP.NET UI controls to our page (a GridView, a DropDownList, and a
ErrorMessage Literal), and added three <asp:LinqDataSource>controls to bind Product, Category, and
Supplier data from it:
Page 22of 59 LINQ to SQL (Part 5 - Binding UI using the ASP:LinqDataSource Control) - Scott...
2008/09/18 file://N:\Programming\KB\Programming\linq-to-sql-part-5-binding-ui-using-the-asp-l...
We then wrote 5 lines of business validation logic in our data model, and 11 lines of UI error handling
logic.
The end result is a simple web application with custom UI that allows users to dynamically filter product
data by category, efficiently sort and page over the product results, inline-edit the product data to save
updates (providing our business rules pass), and delete products from the system (also providing our
business rules allow it).
In future posts in this series I'll cover more LINQ to SQL scenarios including optimistic concurrency, lazy
and eager loading, table mapping inheritance, and custom SQL/SPROC usage.
Next week I also plan to start a new series of blog posts that cover the new <asp:ListView>control - which
is a new control that will ship with the ASP.NET release in .NET 3.5. It provides total control over the
Page 23of 59 LINQ to SQL (Part 5 - Binding UI using the ASP:LinqDataSource Control) - Scott...
2008/09/18 file://N:\Programming\KB\Programming\linq-to-sql-part-5-binding-ui-using-the-asp-l...
markup generated for data scenarios (no tables, no spans, no inline styles...), while also delivering built-in
support for paging, sorting, editing, and insertion scenarios. For example, we could optionally use it to
replace the default Grid layout look of our application above with a completely custom look and feel. Best
of all, I could replace it within the above page in my application and not have to change my Data Model,
the <asp:linqdatasource>declaration, or my code-behind UI error handling logic at all.
Hope this helps,
Scott
Published Monday, J uly 16, 2007 11:03 PM by ScottGu
Filed under: ASP.NET, Visual Studio, .NET, LINQ, Data, SQL Server
Comments
# re: LINQ to SQL (Part 5 - Binding UI using the ASP:LinqDataSource Control)
Tuesday, J uly 17, 2007 3:04 AM by Majid Shahabfar
Well done Scott,
These are great blog series.
I'm waiting for custom SQL/SPROC usage.
# LINQ to SQL (Part 5 - Binding UI using the ASP:LinqDataSource Control)
Tuesday, J uly 17, 2007 4:29 AM by DotNetKicks.com
You've been kicked (a good thing) - Trackback from DotNetKicks.com
# re: LINQ to SQL (Part 5 - Binding UI using the ASP:LinqDataSource Control)
Tuesday, J uly 17, 2007 4:30 AM by Sean Briscoe
Thanks for posting. As usual, I found it only creating more interest for the upcoming .NET 3.5.
# re: LINQ to SQL (Part 5 - Binding UI using the ASP:LinqDataSource Control)
Tuesday, J uly 17, 2007 4:44 AM by Matt
Very nice introduction regarding linqdatasource control
# re: LINQ to SQL (Part 5 - Binding UI using the ASP:LinqDataSource Control)
Tuesday, J uly 17, 2007 4:44 AM by FransBouma
In the part where you display human readable supplier and category names, it's unclear for the reader that these
names are read-in using lazy loading, which means 2 queries per row, as that's how ASP.NET works: per row that
expression is evaluated, which results in a hit to the property 'Supplier' or 'Category' on the active product, which
results in 2 queries per row: one for the supplier, and one for the category. This is really performance intense. Can
you specify a span/prefetch path as well?
Furthermore: the linq datasource suggests that any linq enabled O/R mapper can be used with it, as it is a
LinqDataSource, not a LinqToSqlDataSource. I find this pretty bad, as I fail to see how it can be used with every Linq
enabled O/R mapper out there as it exposes Linq-to-Sql specific features, not generic Linq features in general. This
is shown by the 'tablename' attribute in the HTML tag for the linqdatasource control. What if the Linq enabled O/R
mapper supports inheritance over multiple tables (as Linq to Sql doesn't support) ? Shouldn't it be 'EntityName'
anyway because what if Linq to Sql is going to add entity inheritance over multiple tables in the future, what's the
upgrade path then?
One other thing I want to ask is about the group by option: do you display a warning that after selecting group by, the
Page 24of 59 LINQ to SQL (Part 5 - Binding UI using the ASP:LinqDataSource Control) - Scott...
2008/09/18 file://N:\Programming\KB\Programming\linq-to-sql-part-5-binding-ui-using-the-asp-l...
LINQ to SQL (Part 6 - Retrieving Data Using Stored
Procedures)
Over the last few weeks I've been writing a series of blog posts that cover LINQ to SQL. LINQ to SQL is a
built-in O/RM (object relational mapper) that ships in the .NET Framework 3.5 release, and which enables
you to model relational databases using .NET classes. You can use LINQ expressions to query the
database with them, as well as update/insert/delete data.
Below are the first five parts of my LINQ to SQL series:
Part 1: Introduction to LINQ to SQL
Part 2: Defining our Data Model Classes
Part 3: Querying our Database
Part 4: Updating our Database
Part 5: Binding UI using the ASP:LinqDataSource Control
In these previous LINQ to SQL blog posts I demonstrated how you could use LINQ query expressions to
programmatically retrieve data from a database.
In today's blog post I'll cover how you can also use database stored procedures (SPROCs) and user
defined functions (UDFs) with your LINQ to SQL data model. Today's blog post will specifically cover how
to call SPROCs to query and retrieve data from the database. In my next blog post in this series I'll then
show how you can optionally also use SPROCs to update/insert/delete data from the database.
To SPROC or not to SPROC? That is the question....
The question of whether to use Dynamic SQL generated by an ORM or instead use Stored Procedures
when building a data layer is a topic that generates endless (very passionate) debate amongst developers,
architects and DBAs. A lot of people much smarter than me have written on this topic, so I won't rehash
the arguments for and against each side here.
The LINQ to SQL ORM that ships in .NET 3.5 is pretty flexible, and can be used to create data model
classes whose object model can be independent of the underlying database schema, and which can
encapsulate business logic and validation rules that work regardless of whether the data model is
populated/persisted via dynamic SQL or via SPROCs.
In my LINQ to SQL Part 3: Querying our Database post I discussed how you can write LINQ query
expressions against a LINQ to SQL data model using code like below:
Page 1of 34
LINQtoSQL (Part 6- RetrievingDataUsingStoredProcedures) - ScottGu'sBlog
2008/09/18
file://N:\Programming\KB\Programming\linq- to- sql- part- 6- retrieving- data- using- ...

When you write LINQ query expressions like this the LINQ to SQL ORM will execute the necessary
dynamic SQL for you to retrieve Product objects that matches your query.
As you'll learn in this post, you can also optionally map SPROCs in the database to your LINQ to SQL
DataContext class, which allows you to alternatively retrieve the same Product objects by calling a stored
procedure instead:

This ability to use both dynamic SQL and SPROCs with a clean data model layer is pretty powerful, and
provides a great deal of flexibility when working on projects.
The Steps to Map and Call a SPROC using LINQ to SQL
In my Part 2: Defining our Data Model Classes tutorial I discussed how to use the LINQ to SQL ORM
designer to create a LINQ to SQL class model like below:
Page 2of 34 LINQ to SQL (Part 6 - Retrieving Data Using Stored Procedures) - ScottGu's Blog
2008/09/18 file://N:\Programming\KB\Programming\linq-to-sql-part-6-retrieving-data-using-stor...
Notice above how there are two panes on the LINQ to SQL ORM designer surface. The left pane enables
us to define data model classes that map to our database. The right method pane allows us to optionally
map SPROCs (and UDFs) to our LINQ to SQL DataContext object, which we can then use in-place of
dynamic SQL to populate the data model objects.
How to Map a SPROC to a LINQ to SQL DataContext
To map SPROCs to our DataContext class, let's first go to the VS 2008 Server Explorer window and look
at the SPROCs within our database:
Page 3of 34 LINQ to SQL (Part 6 - Retrieving Data Using Stored Procedures) - ScottGu's Blog
2008/09/18 file://N:\Programming\KB\Programming\linq-to-sql-part-6-retrieving-data-using-stor...

We can double click any of the SPROCs above to open and edit them. For example, below is the
"CustOrderHist" SPROC in Northwind:
To map the above SPROC to our LINQ to SQL DataContext, we can drag/drop it from the Server Explorer
onto our LINQ to SQL ORM designer. This will automatically create a new method on our LINQ to SQL
DataContext class like below:
Page 4of 34 LINQ to SQL (Part 6 - Retrieving Data Using Stored Procedures) - ScottGu's Blog
2008/09/18 file://N:\Programming\KB\Programming\linq-to-sql-part-6-retrieving-data-using-stor...
By default the method name created on the DataContext class will be the same as the SPROC name, and
the return type of the method will be an automatically created type that follows the "[SprocName]Result"
naming pattern. For example: the SPROC above would return a sequence of "CustOrderHistResult"
objects. We could optionally change the name of the method by selecting it in the designer and then use
the property grid to rename it.
How to Call our Newly Mapped SPROC
Once we've done the steps above to map a SPROC onto our DataContext class, it is easy to use it to
programmatically retrieve data. All we need to-do is call the new method we mapped on our DataContext
class to get back a sequence of strongly typed results from the SPROC:
Calling the SPROC in VB:

Calling the Sproc in C#:
Page 5of 34 LINQ to SQL (Part 6 - Retrieving Data Using Stored Procedures) - ScottGu's Blog
2008/09/18 file://N:\Programming\KB\Programming\linq-to-sql-part-6-retrieving-data-using-stor...

In addition to programming looping over the result like in the code samples above, I could also obviously
bind the results to any UI control to display them. For example, the below code databinds the result of our
SPROC to a <asp:gridview>control:

Which then displays the product history of our customer on a page like so:
Page 6of 34 LINQ to SQL (Part 6 - Retrieving Data Using Stored Procedures) - ScottGu's Blog
2008/09/18 file://N:\Programming\KB\Programming\linq-to-sql-part-6-retrieving-data-using-stor...

Mapping the Return Type of SPROC Methods to Data Model Classes
In the "CustOrderHist" SPROC example above the stored procedure returned a sequence of product
history results containing two columns of data: the ProductName of the product, and the Total Number of
orders the customer has made for that product. The LINQ to SQL designer automatically defined a new
"CustOrderHistResult" class to represent this result.
We could alternatively choose to have the return result of a SPROC map to an existing data model class
we have already defined in the LINQ to SQL designer (for example: an existing Product or Order entity
class).
For example, assume we have a "GetProductsByCategory" SPROC in our database that returns product
information like so:

Page 7of 34 LINQ to SQL (Part 6 - Retrieving Data Using Stored Procedures) - ScottGu's Blog
2008/09/18 file://N:\Programming\KB\Programming\linq-to-sql-part-6-retrieving-data-using-stor...
Like before we can create a "GetProductsByCategory" method on our DataContext that calls this SPROC
by dragging it onto our LINQ to SQL designer. Rather than just dropping the SPROC anywhere on the
designer, though, we'll instead drop the SPROC on top of the existing "Product" class in our data model
designer:
This gesture of dropping the SPROC onto the Product class tells the LINQ to SQL designer to have the
"GetProductsByCategory" method return a sequence of "Product" objects as a return result:
Page 8of 34 LINQ to SQL (Part 6 - Retrieving Data Using Stored Procedures) - ScottGu's Blog
2008/09/18 file://N:\Programming\KB\Programming\linq-to-sql-part-6-retrieving-data-using-stor...

One of the cool things about having our SPROC return "Product" objects like above is that LINQ to SQL
will automatically track the changes made to the returned Product objects just like it would Product objects
returned via LINQ queries. When we call the "SubmitChanges()" method on our DataContext, the
changes we have made to these objects will automatically be saved back to the database.
For example, we could write the code below to retrieve (using a SPROC) and change the price of all
products within a specific Category to be 90% of their current value:

When we call SubmitChanges() at the end it will transactionally update all of the product prices. To
understand more about how change tracking and the SubmitChanges() method work, as well as about
how Validation Business Logic can be added to data model entities, please read my LINQ to SQL Part 4:
Updating our Database tutorial.
In my next blog post in this LINQ to SQL series I'll also cover how you can replace the dynamic
insert/update/delete SQL generated by the ORM with custom SPROCs that handle the database updates
instead. The nice thing is that the code above wouldn't change at all if I configured my DataContext to use
SPROCs for updates - it would purely be a mapping layer change and the code written against my data
model would be oblivious to it.
Handling SPROC Output Parameters
Page 9of 34 LINQ to SQL (Part 6 - Retrieving Data Using Stored Procedures) - ScottGu's Blog
2008/09/18 file://N:\Programming\KB\Programming\linq-to-sql-part-6-retrieving-data-using-stor...
LINQ to SQL maps "out" parameters in SPROCs as reference parameters (ref keyword), and for value
types declares the parameter as nullable.
For example, consider the below "GetCustomerDetails" SPROC which takes a CustomerID as an input
parameter, and which returns the company name as an output parameter in addition to its order history as
a query result:

If we drag the above SPROC onto our "Order" class in the LINQ to SQL designer, we could then write the
below code to call it:
VB:

C#:
Page 10of 34 LINQ to SQL (Part 6 - Retrieving Data Using Stored Procedures) - ScottGu's Blog
2008/09/18 file://N:\Programming\KB\Programming\linq-to-sql-part-6-retrieving-data-using-stor...
Notice in the code above how the SPROC helper method returns back a sequence of Order objects - but
also then returns the CompanyName as an output parameter to the helper method.
Handling Multiple Result Shapes from SPROCs
When a stored procedure can return multiple result shapes, the return type of the SPROC method on the
DataContext cannot be strongly typed to a single class shape. For example, consider the SPROC below
which returns either a product result or an order result depending on the input parameter:

LINQ to SQL supports the ability to create SPROC helper methods that can return either a Product or
Order shape by adding a partial "NorthwindDataContext" class to the project that defines a method (which
in this case we'll call "VariablesShapeSample") that invokes the SPROC and returns an IMultipleResult
object like so:
VB:
Page 11of 34 LINQ to SQL (Part 6 - Retrieving Data Using Stored Procedures) - ScottGu's Blog
2008/09/18 file://N:\Programming\KB\Programming\linq-to-sql-part-6-retrieving-data-using-stor...
C#:
Once this method is added into our project we can then call it and convert the result to be either a Product
or Order sequence when we are using it:
VB:
Page 12of 34 LINQ to SQL (Part 6 - Retrieving Data Using Stored Procedures) - ScottGu's Blog
2008/09/18 file://N:\Programming\KB\Programming\linq-to-sql-part-6-retrieving-data-using-stor...

C#:

Supporting User Defined Functions (UDFs)
In addition to SPROCS, LINQ to SQL also supports both scalar-valued and table-valued user
Page 13of 34 LINQ to SQL (Part 6 - Retrieving Data Using Stored Procedures) - ScottGu's Blog
2008/09/18 file://N:\Programming\KB\Programming\linq-to-sql-part-6-retrieving-data-using-stor...
defined functions (UDFs), as well as the in-line counterpart to both. Once added to your DataContext as a
method, you can use these UDF functions within your LINQ queries.
For example, consider a simple scalar user defined function called "MyUpperFunction":
We can drag/drop it from the Visual Studio Server Explorer onto our LINQ to SQL Designer to add it as a
method on our DataContext:

We can then use this UDF function inline within our LINQ expressions when writing queries against our
LINQ to SQL data model (notice it is being used within the "where" clause below):
VB:
C#:
Page 14of 34 LINQ to SQL (Part 6 - Retrieving Data Using Stored Procedures) - ScottGu's Blog
2008/09/18 file://N:\Programming\KB\Programming\linq-to-sql-part-6-retrieving-data-using-stor...
If you use the LINQ to SQL Debug Visualizer that I blogged about here, you can see how LINQ to SQL
transforms the above expression queries into raw SQL that execute the UDF inside the database at
runtime:
Summary
LINQ to SQL supports the ability to call Stored Procedures and UDFs within the database and nicely
integrate them into our data model. In this blog post I demonstrated how you can use SPROCs to easily
retrieve data and populate our data model classes. In my next blog post in this series I'll cover how you
can also use SPROCs to override the update/insert/delete logic when you SubmitChanges() on your
DataContext to persist back to the database.
Hope this helps,
Scott
Published Thursday, August 16, 2007 2:16 AM by ScottGu
Filed under: ASP.NET, .NET, LINQ, Data, SQL Server
Comments
# re: LINQ to SQL (Part 6 - Retrieving Data Using Stored Procedures)
Thursday, August 16, 2007 5:50 AM by Ibrahim Mohammed
Page 15of 34 LINQ to SQL (Part 6 - Retrieving Data Using Stored Procedures) - ScottGu's Blog
2008/09/18 file://N:\Programming\KB\Programming\linq-to-sql-part-6-retrieving-data-using-stor...
LINQ to SQL (Part 7 - Updating our Database using
Stored Procedures)
Over the last few weeks I've been writing a series of blog posts that cover LINQ to SQL. LINQ to SQL is a
built-in O/RM (object relational mapper) that ships in the .NET Framework 3.5 release, and which enables
you to model relational databases using .NET classes. You can use LINQ expressions to query the
database with them, as well as update/insert/delete data.
Below are the first six parts in this series:
Part 1: Introduction to LINQ to SQL
Part 2: Defining our Data Model Classes
Part 3: Querying our Database
Part 4: Updating our Database
Part 5: Binding UI using the ASP:LinqDataSource Control
Part 6: Retrieving Data Using Stored Procedures
In part 6 I demonstrated how you can optionally use database stored procedures (SPROCs) and user
defined functions (UDFs) to query and retrieve data using your LINQ to SQL data model. In today's blog
post I'm going to discuss how you can also optionally use SPROCs to update/insert/delete data from the
database.
To help illustrate this - let's start from scratch and build-up a data access layer for the Northwind sample
database:
Step 1: Creating our Data Access Layer (without using SPROCs yet)
In my Part 2: Defining our Data Model Classes tutorial I discussed how to use the LINQ to SQL ORM
designer that is built-in to VS 2008 to create a LINQ to SQL class model like below:
Page 1of 34
LINQtoSQL (Part 7- Updatingour DatabaseusingStoredProcedures) - ScottGu's...
2008/09/18
file://N:\Programming\KB\Programming\linq- to- sql- part- 7- updating- our- database...
Adding Validation Rules to our Data Model Classes
After defining our data model classes and relationships we'll want to add some business logic validation to
our data model. We can do this by adding partial classes to our project that add validation rules to our
data model classes (I cover how to-do this in-depth in my Part 4: Updating our Database LINQ to SQL
tutorial).
For example, we could add validation rules to enforce that the Customer's phone number follows a valid
phone pattern, and that we don't add Orders where the customer's RequiredDate for delivery is before the
actual OrderDate of the Order. Once defined in partial classes like below, these validation methods will
automatically be enforced anytime we write code to update our data model objects in an application.
VB:
Page 2of 34 LINQ to SQL (Part 7 - Updating our Database using Stored Procedures) - ScottGu's B...
2008/09/18 file://N:\Programming\KB\Programming\linq-to-sql-part-7-updating-our-database-usi...
C#:
Page 3of 34 LINQ to SQL (Part 7 - Updating our Database using Stored Procedures) - ScottGu's B...
2008/09/18 file://N:\Programming\KB\Programming\linq-to-sql-part-7-updating-our-database-usi...
Adding a GetCustomer() Helper Method to our DataContext
Now that we have our data model classes created, and have applied validation rules to them, we can
query and interact with the data. We can do this by writing LINQ expressions against our data model
classes to query the database and populate them (I cover how to-do this in my Part 3: Querying our
Database LINQ to SQL tutorial). Alternatively we could map SPROCs to our DataContext and use them to
populate the data model classes (I cover how to-do this in my Part 6: Retrieving Data using Stored
Procedures LINQ to SQL tutorial).
When building a LINQ to SQL data layer you'll usually want to encapsulate common LINQ queries (or
SPROC invocations) into helper methods that you add to your DataContext class. We can do this by
adding a partial class to our project. For example, we could add a helper method called "GetCustomer()"
that enables us to lookup and retrieve a Customer object from the database based on their CustomerID
value:
VB:
Page 4of 34 LINQ to SQL (Part 7 - Updating our Database using Stored Procedures) - ScottGu's B...
2008/09/18 file://N:\Programming\KB\Programming\linq-to-sql-part-7-updating-our-database-usi...
C#:
Step 2: Using our Data Access Layer (still without SPROCs)
We now have a data access layer that encapsulates our data model, integrates business validation rules,
and enables us to query, update, insert, and delete the data.
Let's look at a simple scenario using it where we retrieve an existing customer object, update the
customer's ContactName and Phone Number, and then create a new Order object and associate it with
them. We can write the below code to do all of this within a single transaction. LINQ to SQL will ensure
that our business logic validation rules are clean before saving anything in the database:
VB:
Page 5of 34 LINQ to SQL (Part 7 - Updating our Database using Stored Procedures) - ScottGu's B...
2008/09/18 file://N:\Programming\KB\Programming\linq-to-sql-part-7-updating-our-database-usi...

C#:

LINQ to SQL monitors the modifications we make to the objects we retrieve from the DataContext, and
keeps track of all of the objects we add into it. When we call DataContext.SubmitChanges() at the end,
LINQ to SQL will check that our business logic rules are valid, and if so automatically generate the
appropriate dynamic SQL to update our Customer record above, and insert a new record into the Orders
Page 6of 34 LINQ to SQL (Part 7 - Updating our Database using Stored Procedures) - ScottGu's B...
2008/09/18 file://N:\Programming\KB\Programming\linq-to-sql-part-7-updating-our-database-usi...
table.
Hang on a second - I thought this post was about using SPROCs???
If you are still reading this, you might be feeling confused about where SPROCs fit into this post. Why did
I show you above how to write code that works with our data model objects, and then causes dynamic
SQL to run? Why haven't I showed you how to call a SPROC for doing inserts/updates/deletes instead
yet?
The reason is that the programming model in LINQ to SQL for working with data model objects backed by
SPROCs is the same as those updated via dynamic SQL. The way you add data model validation logic is
exactly the same (so all the validation rules on our data model classes above still apply when we use
SPROCs). The code snippet above where we use our data access layer to retrieve a customer, update it,
and then add a new order associated with it is also exactly the same regardless of whether we are
using dynamic SQL for updates, or whether we have configured our data model classes to use SPROCs
instead.
This programming model symmetry is powerful both in that you don't have to learn two ways of doing
things, and also because it means that you don't have to decide up front at the beginning of your project
whether you are going to use SPROCs or not. You can start off using the dynamic SQL support provided
by the LINQ to SQL ORM for all queries, inserts, updates and deletes. You can then add your
business and validation rules to your model. And then later you can optionally update your data mapping
model to use SPROCs - or not if you decide you don't want to. The code and tests you write against your
data model classes can stay the same regardless of whether you use dynamic SQL or SPROCs.
We'll now spend the rest of this blog post demonstrating how we can update the data model we've built to
use SPROCs for updates/inserts/deletes - while still using the same validation rules, and working with the
same code snippets above.
How to Use SPROCs for Insert/Update/Delete Scenarios
We can modify the data access layer we've been building to use SPROCs to handle updates, instead of
dynamic SQL, in one of two ways:
1) By using the LINQ to SQL designer to graphically configure SPROCs to execute in response to
Insert/Update/Delete operations on our data model classes.
or:
2) By adding a NorthwindDataContext partial class in our project, and then by implementing the
appropriate Insert/Update/Delete partial methods provided on it (for example: InsertOrder, UpdateOrder,
DeleteOrder) that will be called when we insert/update/delete data model objects. These partial methods
will be passed the data model instances we want to update, and we can then execute whatever SPROC or
SQL code we want to save it within the database.
When we use approach #1 (the LINQ to SQL designer) to graphically configure SPROCs to call, it is under
the covers generating the same code (in a partial class it creates) that you'd write when using approach
#2. In general I'd recommend using the LINQ to SQL designer to configure the SPROCs for the 90% case
- and then in more advanced scenarios go in and custom tweak the SPROC invocation code it generates
if you need to.
Step 3: Doing Order Inserts with a SPROC
We'll begin switching our data model to use SPROCs by starting with the Order object.
We'll first go to the Visual Studio "Server Explorer" window, expand into the "Stored Procedures" node of
our database, and then right-click and choose "Add New Stored Procedure":
Page 7of 34 LINQ to SQL (Part 7 - Updating our Database using Stored Procedures) - ScottGu's B...
2008/09/18 file://N:\Programming\KB\Programming\linq-to-sql-part-7-updating-our-database-usi...

We'll then create a new SPROC that we'll call "InsertOrder" that inserts a new order record into our Orders
table:
Page 8of 34 LINQ to SQL (Part 7 - Updating our Database using Stored Procedures) - ScottGu's B...
2008/09/18 file://N:\Programming\KB\Programming\linq-to-sql-part-7-updating-our-database-usi...
Notice above how the SPROC defines the "OrderID" parameter as an output param. This is because the
OrderID column in the database is an identity column that is set to auto-increment each time a new record
is added. The caller of the SPROC will pass in NULL as a value when calling it - and the SPROC then
passes back the newly created OrderID value as the output value (by calling the SCOPE_IDENTITY()
function at the end of the SPROC).
After creating the SPROC we'll then open up the LINQ to SQL ORM designer for our data access layer.
Like I discussed in my last blog post in this series (Part 6: Retrieving Data Using Stored Procedures), we
can drag/drop SPROCs from the server-explorer onto the method pane of our DataContext designer.
We'll want to-do this with our newly created InsertOrder SPROC:
Our last step will be to tell our data access layer to use the InsertOrder SPROC when inserting new Order
objects into the database. We can do that by selecting the "Order" class in the LINQ to SQL ORM
designer, and then by going to the property grid and clicking the "..." button to override how Insert
operations happen for it:
Page 9of 34 LINQ to SQL (Part 7 - Updating our Database using Stored Procedures) - ScottGu's B...
2008/09/18 file://N:\Programming\KB\Programming\linq-to-sql-part-7-updating-our-database-usi...
Clicking the "..." button will bring up a dialog that allows us to customize how insert operations happen:
Page 10of 34 LINQ to SQL (Part 7 - Updating our Database using Stored Procedures) - ScottGu'...
2008/09/18 file://N:\Programming\KB\Programming\linq-to-sql-part-7-updating-our-database-usi...

Notice above how the default mode ("Use Runtime") is to have LINQ to SQL calculate and execute
dynamic SQL to handle the insert operations. We can change that by selecting the "Customize" radio
button and then pick our InsertOrder SPROC from the list of available SPROCs:
Page 11of 34 LINQ to SQL (Part 7 - Updating our Database using Stored Procedures) - ScottGu'...
2008/09/18 file://N:\Programming\KB\Programming\linq-to-sql-part-7-updating-our-database-usi...

The LINQ to SQL designer will populate a parameter list for the SPROC we picked, and enable us to map
properties on our Order class to parameters of our InsertOrder SPROC. By default it is smart and tries to
"best match" them based on name. You can go in and override them if you want.
Once we click "ok" on the dialog, we are done. Now whenever a new Order is added to our DataContext
and the SubmitChanges() method is invoked, our InsertOrder SPROC will be used instead of executing
dynamic SQL.
Important: Even though we are now using a SPROC for persistence, the custom Order "OnValidate()"
partial method we created earlier (in step 1 of this blog post) to encapsulate Order validation rules still
executes before any changes are saved or the SPROC is invoked. This means we have a clean way to
encapsulate business and validation rules in our data models, and can re-use them regardless of whether
dynamic SQL or SPROCs are used.
Step 4: Doing Customer Updates with a SPROC
Now let's modify our Customer object to handle updates using a SPROC.
We'll start by creating a new "UpdateCustomer" SPROC like below:
Page 12of 34 LINQ to SQL (Part 7 - Updating our Database using Stored Procedures) - ScottGu'...
2008/09/18 file://N:\Programming\KB\Programming\linq-to-sql-part-7-updating-our-database-usi...
Notice above how in addition to passing in the @CustomerID parameter, we are also passing in a
@Original_CustomerID parameter. The CustomerID column in the Customers table is not an auto-
increment identity column, and it can be modified as part of an update of the Customer object.
Consequently we need to be able to provide the SPROC with both the original CustomerID and the new
CustomerID in order to update the record. We'll look at how we map this using the LINQ to SQL designer
shortly.
You'll notice above how I'm also passing in a @Version parameter (which is a timestamp) to the SPROC.
This is a new column I've added to the Northwind Customers table to help handle optimistic concurrency. I
will cover optimistic concurrency in much more depth in a later blog post in this LINQ to SQL series - but
the short summary is that LINQ to SQL fully supports optimistic concurrency, and enables you to use
either a version timestamp or to supply both original/new values to your SPROCs to detect if changes
have been made by another user since you last refreshed your data objects. For this sample I'm using a
timestamp since it makes the code much cleaner.
Once we've created our SPROC, we can drag/drop it onto the LINQ to SQL designer to add it as a method
on our DataContext. We can then select the Customer class in the ORM designer and click the "..." button
to override the Customer object's Update behavior in the property grid:
Page 13of 34 LINQ to SQL (Part 7 - Updating our Database using Stored Procedures) - ScottGu'...
2008/09/18 file://N:\Programming\KB\Programming\linq-to-sql-part-7-updating-our-database-usi...

We'll select the "Customize" radio button and pick our UpdateCustomer SPROC to use:
Page 14of 34 LINQ to SQL (Part 7 - Updating our Database using Stored Procedures) - ScottGu'...
2008/09/18 file://N:\Programming\KB\Programming\linq-to-sql-part-7-updating-our-database-usi...

When mapping our Customer object's properties to the SPROC parameters, you'll notice that we'll want to
be deliberate about whether we supply the "current" property value on the data object, or the original value
that was in the database when the object was first retrieved. For example, we'll want to make sure we
map the "current" value of the Customer.CustomerID property for the @CustomerID SPROC parameter,
and that we map the original value for the @original_customerID SPROC parameter.
Once we click "ok" on the dialog, we are done. Now whenever a new Customer is updated and the
SubmitChanges() method is invoked, our UpdateCustomer SPROC will be used instead of executing
dynamic SQL.
Important: Even though we are now using a SPROC for persistence, the Customer "OnPhoneChanging()"
partial method we created earlier (in step 1 of this blog post) to encapsulate Phone Number validation
rules still executes before any changes are saved or the SPROC is invoked. We have a clean way to
encapsulate business and validation rules in our data models, and can re-use them regardless of whether
dynamic SQL or SPROCs are used.
Step 5: Using our Data Access Layer Again (this time with SPROCs)
Once we've updated our data layer to use SPROCs instead of dynamic SQL for persistence, we can re-
Page 15of 34 LINQ to SQL (Part 7 - Updating our Database using Stored Procedures) - ScottGu'...
2008/09/18 file://N:\Programming\KB\Programming\linq-to-sql-part-7-updating-our-database-usi...
run the exact same code we wrote in Step 2 earlier against our data model classes:

Now the updates for the Customer object, and the insert for the Order object, are executing via SPROCs
instead of dynamic SQL. The validation logic we defined still executes just like before, though, and the
data access code we write to use the data model classes is exactly the same.
Some Advanced Notes When Using SPROCs
A few quick notes that you might find useful for more advanced SPROC scenarios with LINQ to SQL:
Usage of SPROC Output Params:
In the Insert scenario (Step 3) above I showed how we could return back the new OrderID value (which is
an auto-increment identity column in the Orders table) using an output parameter of the SPROC. You
aren't limited to only returning back identity column values when using SPROCs with LINQ to SQL - in fact
you can update and return back output values for any parameter of your SPROC. You can use this
approach both for Insert and Update scenarios. LINQ to SQL will then take the return value and use it to
update the property value of your data model object without you having to-do any second queries against
the database to refresh/populate them.
What Happens if the SPROC Throws an Error?
If a SPROC raises an error when doing an Insert/Update/Delete operation, LINQ to SQL will automatically
cancel and rollback the transaction of all changes associated with the current SubmitChanges() call on the
DataContext. This ensures that your data is always kept in a clean, consistent state.
Can you write code instead of using the ORM designer to call SPROCs?
As I mentioned earlier in this post, you can use either the LINQ to SQL ORM designer to map your
insert/update/delete operations to SPROCs, or you can add partial methods on your DataContext class
and programmatically invoke them yourself. Here is an example of the explicit code you could write in a
partial class for the NorthwindDataContext to override the UpdateCustomer behavior to call a SPROC:
Page 16of 34 LINQ to SQL (Part 7 - Updating our Database using Stored Procedures) - ScottGu'...
2008/09/18 file://N:\Programming\KB\Programming\linq-to-sql-part-7-updating-our-database-usi...
The code above was actually what was generated by the LINQ to SQL ORM designer when we used the
designer to map the SPROC and then associate the update behavior of the Customer object with it. You
can use it as a starting point and then add any additional logic you want to it to make it more advanced (for
example: use the return value of the SPROC to raise custom exceptions for error conditions, optimistic
concurrency, etc).
Summary
LINQ to SQL is a very flexible ORM. It enables you to write clean object-oriented code to retrieve, update
and insert data.
Best of all - it enables you to cleanly design data model classes independent of how they are persisted
and loaded from a database. You can use the built-in ORM engine to efficiently retrieve and update data
in the database using dynamic SQL. Or alternatively you can configure your data layer to use SPROCs.
The nice thing is that your code consuming the data layer, and all of the business logic validation rules you
annotate it with, can be the same regardless of which persistence approach you use.
In future blog posts in this series I'll cover some remaining LINQ to SQL concepts including: Single Table
Inheritance, Deferred/Eager Loading, Optimistic Concurrency, and handling Multi-Tier scenarios. I'm on
vacation next week, and so will hopefully have some free time to get a few of them written then.
Hope this helps,
Scott
Published Thursday, August 23, 2007 1:27 AM by ScottGu
Filed under: ASP.NET, Visual Studio, .NET, LINQ, Data
Comments
# re: LINQ to SQL (Part 7 - Updating our Database using Stored Procedures)
Thursday, August 23, 2007 5:16 AM by Per
Yet another great article.
Your articles alone would be great first chapters of one of the many "missing" books on the topic LINQ to SQL.
Looking forward the "Multi-Tier" part.
I think you have to review your defenition of vacation... :p
"I'm on vacation next week, and so will hopefully have some free time to get a few of them written then"
peace.
# re: LINQ to SQL (Part 7 - Updating our Database using Stored Procedures)
Page 17of 34 LINQ to SQL (Part 7 - Updating our Database using Stored Procedures) - ScottGu'...
2008/09/18 file://N:\Programming\KB\Programming\linq-to-sql-part-7-updating-our-database-usi...
LINQ to SQL (Part 9 - Using a Custom LINQ
Expression with the <asp:LinqDatasource> control)
Over the last few weeks I've been writing a series of blog posts that cover LINQ to SQL. LINQ to SQL is a
built-in O/RM (object relational mapper) that ships in the .NET Framework 3.5 release, and which enables
you to model relational databases using .NET classes. You can use LINQ expressions to query the
database with them, as well as update/insert/delete data.
Below are the first eight parts in this series:
Part 1: Introduction to LINQ to SQL
Part 2: Defining our Data Model Classes
Part 3: Querying our Database
Part 4: Updating our Database
Part 5: Binding UI using the ASP:LinqDataSource Control
Part 6: Retrieving Data Using Stored Procedures
Part 7: Updating our Database using Stored Procedures
Part 8: Executing Custom SQL Expressions
In Part 5 of the series I introduced the new <asp:LinqDataSource>control in .NET 3.5 and talked about
how you can use it to easily bind ASP.NET UI controls to LINQ to SQL data models. I also demonstrated
how to use it a little more in a follow-up post I did that discusses the new <asp:ListView>control (Part 1 -
Building a Product Listing Page with Clean CSS UI).
In both of these articles the queries I performed were relatively straight-forward (the where clause worked
against a single table of data). In today's blog post I'll demonstrate how to use the full
query expressiveness of LINQ with the LinqDataSource control, and show how you can use any LINQ to
SQL query expression with it.
Quick Recap: <asp:LinqDataSource> with a Declarative Where Statement
In these two posts I demonstrated how you can use the built-in filter capabilities of the LinqDataSource
control to declaratively express a filter statement on a LINQ to SQL data model.
For example, assuming we had created a LINQ to SQL data model for the Northwind database (which I
covered how to-do in Part 2 of this series), we could declare a <asp:LinqDataSource>control on the page
with a declarative <where>filter that returns back only those products in a specific category (specified
via a querystring "categoryid" value):
We could then point a <asp:gridview>control at the datasource and enable paging, editing, and sorting on
it:
Page 1of 25
LINQtoSQL (Part 9- UsingaCustomLINQExpressionwiththe<asp:LinqDatasou...
2008/09/18
file://N:\Programming\KB\Programming\linq- to- sql- part- 9- using- a- custom- linq- ...
When we run the above page we'll then have a GridView with automatic sorting, paging, and editing
support against our Product data model:
Using declarative <where>parameters like above works well for many common scenarios. But what
happens if you want the Product filtering to be richer or more complex? For example, what if we only
Page 2of 25 LINQ to SQL (Part 9 - Using a Custom LINQ Expression with the <asp:LinqDatasou...
2008/09/18 file://N:\Programming\KB\Programming\linq-to-sql-part-9-using-a-custom-linq-expr...
wanted to display products made by suppliers based in a dynamic set of countries?
Using the <asp:LinqDataSource> Selecting Event
To handle custom query scenarios you can implement an event handler to handle the "Selecting" event on
the <asp:LinqDataSource>control. Within this event handler you can write whatever code you want to
retrieve a data model result. You could do this with a LINQ to SQL query expression, or call a Stored
Procedure or use a Custom SQL Expression to retrieve the LINQ to SQL data model. Once you retrieve a
sequence of data, all you need to-do is to assign it to the "Result" property on the
LinqDataSourceSelectEventArgs object. The <asp:LinqDataSource>will then use this sequence as its
data to work with.
For example, below is a LINQ to SQL query expression that retrieves only products from suppliers based
in a specific set of countries:
VB:
C#:
Note: you do not need to write your query expression in-line within the event handler. A
cleaner approach would be to encapsulate it within a helper method that you just call from
the event handler. I show how to create one of these helper methods in the beginning of my
Part 8 blog post (using a GetProductsByCategory helper method).
Now when we run our page using the custom Selecting event handler, we'll only see those products
whose suppliers are located in our array of countries:
Page 3of 25 LINQ to SQL (Part 9 - Using a Custom LINQ Expression with the <asp:LinqDatasou...
2008/09/18 file://N:\Programming\KB\Programming\linq-to-sql-part-9-using-a-custom-linq-expr...
One of the really cool things to notice above is that paging and sorting still work with our GridView - even
though we are using a custom Selecting event to retrieve the data. This paging and sorting logic happens
in the database - which means we are only pulling back the 10 products from the database that we need to
display for the current page index in the GridView (making it super efficient).
You might ask yourself - how is it possible that we get efficient paging and sorting support even when
using a custom selecting event? The reason is because LINQ uses a deferred execution model - which
means that the query doesn't actually execute until you try and iterate over the results. One of the benefits
of this deferred execution model is that it enables you to nicely compose queries out of other queries, and
effectively "add-on" behavior to them. You can learn more about this in my LINQ to SQL Part 3 blog post.
In our "Selecting" event handler above we are declaring a custom LINQ query we want to execute and are
then assigning it to the "e.Result" property. We haven't actually executed it yet though (since we didn't try
and iterate through the results or call ToArray() or ToList() on it). The LINQDataSource is therefore able to
automatically append on a Skip() and Take() operator to the query, as well as apply an "orderby"
expression to it -- all of these values being automatically calculated from the page index and sort
preference of the GridView. Only then does the LINQDataSource execute the LINQ expression and
retrieve the data. LINQ to SQL then takes care of making sure that the sort and page logic is handled in
the database - and that only the 10 product rows required are returned from it.
Notice below how we can also still use the GridView to edit and delete data, even when using a custom
LinqDataSource "Selecting" event:
Page 4of 25 LINQ to SQL (Part 9 - Using a Custom LINQ Expression with the <asp:LinqDatasou...
2008/09/18 file://N:\Programming\KB\Programming\linq-to-sql-part-9-using-a-custom-linq-expr...
This editing/deleting support will work as long as our Selecting event assigns a Result query whose result
sequence is of regular entity objects (for example: a sequence of type Product, Supplier, Category, Order,
etc). The LINQDataSource can then automatically handle cases where UI controls perform updates
against them.
To learn more about how updates work with LINQ to SQL, please read Part 4 of this series. Then read
Part 5 of the series to see Updates in action with the LinqDataSource.
Performing Custom Query Projections with the Selecting Event
One of the powerful features of LINQ is its ability to custom "shape" or "project" data. You can do this in a
LINQ to SQL expression to indicate that you want to retrieve only a subset of values from an entity, and/or
to dynamically compute new values on the fly using custom expressions that you define. You can learn
more about how these LINQ query projection/shaping capabilities in Part 3 of this series.
For example, we could modify our "Selecting" event handler to populate a GridView to display a custom
set of Product information. In this Grid we'll want to display the ProductID, Product Name, Product
UnitPrice, the Number of Orders made for this Product, and the total Revenue collected from orders
placed for the Product. We can dynamically compute these last two values using a LINQ expression like
below:
VB:
Page 5of 25 LINQ to SQL (Part 9 - Using a Custom LINQ Expression with the <asp:LinqDatasou...
2008/09/18 file://N:\Programming\KB\Programming\linq-to-sql-part-9-using-a-custom-linq-expr...
C#:
Note: The Sum method used in the Revenue statement above is an example of an Extension
Method. The function it takes is an example of a Lambda expression. The resulting type
created by the LINQ query expression is an anonymous type - since its shape is inferred
from the query expression. Extension Methods, Lambda Expressions, and Anonymous
Types are all new language features of VB and C# in VS 2008.
The result of our custom LINQ expression when bound to the GridView will be UI like below:
Page 6of 25 LINQ to SQL (Part 9 - Using a Custom LINQ Expression with the <asp:LinqDatasou...
2008/09/18 file://N:\Programming\KB\Programming\linq-to-sql-part-9-using-a-custom-linq-expr...
Note that paging and sorting still work above with our GridView - even though we are using a custom LINQ
shape/projection for the data.
One feature that will not work with custom shapes/projections, though, is inline editing support. This is
because we are doing a custom projection in our Selecting event, and so the LinqDataSource has no way
to safely know how to update an underlying entity object. If we want to add editing support to the GridView
with a custom shaped type, we'd want to either move to using an ObjectDataSource control (where we
could supply a custom Update method method to handle the updates), or have the user navigate to a new
page when performing updates - and display a DetailsView or FormView control that was bound to a
Product entity for editing (and not try and do inline editing with the grid).
Summary
You can easily perform common query operations against a LINQ to SQL data model using the built-in
declarative filtering support of the LinqDataSource.
To enable more advanced or custom filtering expressions, you can take advantage of the
LINQDataSource's Selecting event. This will enable you to perform any logic you want to retrieve and filter
LINQ to SQL data. You can call methods to retrieve this data, use LINQ Query Expressions, call a Stored
Procedures, or invoke a Custom SQL Expression to-do this.
Hope this helps,
Scott
Published Friday, September 07, 2007 11:52 PM by ScottGu
Filed under: ASP.NET, .NET, LINQ, Data

Comments
Page 7of 25 LINQ to SQL (Part 9 - Using a Custom LINQ Expression with the <asp:LinqDatasou...
2008/09/18 file://N:\Programming\KB\Programming\linq-to-sql-part-9-using-a-custom-linq-expr...

You might also like