Tải bản đầy đủ (.pdf) (10 trang)

Professional ASP.NET 3.5 in C# and Visual Basic Part 54 pps

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (276.92 KB, 10 trang )

Evjen c09.tex V2 - 01/28/2008 2:09pm Page 486
Chapter 9: Querying with LINQ
Me.GridView1.DataBind()
End Sub
C#
protected void Page_Load(object sender, EventArgs e)
{
MoviesDataContext dc = new MoviesDataContext();
var query = from m in dc.Movies
select m;
System.Diagnostics.Debug.WriteLine(query);
this.GridView1.DataSource = query;
this.GridView1.DataBind();
}
Now, when you debug the Web site using Visual Studio, you can see the SQL query, as shown
in Figure 9-11.
Figure 9-11 The SQL query generated by LINQ to SQL
As you can see, the SQL generated is standard SQL syntax, and LINQ is quite good at optimizing the
queries it generates, even for more complex queries such as the grouping query shown in Listing 9-26.
Listing 9-26: Grouping LINQ to SQL data
VB
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs)
Dim dc As New MoviesDataContext()
Dim query = From m In dc.Movies _
Group By m.Genre Into g = Group, Count()
System.Diagnostics.Debug.WriteLine(query)
Me.GridView1.DataSource = query
486
Evjen c09.tex V2 - 01/28/2008 2:09pm Page 487
Chapter 9: Querying with LINQ
Me.GridView1.DataBind()


End Sub
C#
protected void Page_Load(object sender, EventArgs e)
{
MoviesDataContext dc = new MoviesDataContext();
var query = from m in dc.Movies
group m by m.Genre into g
select new { Genre = g.Key, Count = g.Count() };
System.Diagnostics.Debug.WriteLine(query);
this.GridView1.DataSource = query;
this.GridView1.DataBind();
}
The generated SQL for this query is shown in Figure 9-12.
Figure 9-12 Grouping SQL data
using LINQ to SQL
Note that SQL to LINQ generates SQL that is optimized for SQL Server 2005.
LINQ also includes a logging option you can enable by setting the Log property of the data context.
While LINQ to SQL does an excellent job generating the SQL query syntax, there may be times where it is
more appropriate to use other SQL query methods, such as Stored Procedures, or Views. LINQ supports
using the predefined queries as well.
To use a SQL View with LINQ to SQL, you simply drag the View onto the LINQ to SQL design surface
just as you would a standard SQL table. Views appear on the design surface, just as the tables we added
earlier. Once the View is on the design surface, you can execute queries against it, just as you did the SQL
tables. This is shown in Listing 9-27.
487
Evjen c09.tex V2 - 01/28/2008 2:09pm Page 488
Chapter 9: Querying with LINQ
Listing 9-27: Querying LINQ to SQL data using a View
VB
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs)

Dim dc As New MoviesDataContext()
Dim query = From m In dc.AllMovies _
Select m
System.Diagnostics.Debug.WriteLine(query)
Me.GridView1.DataSource = query
Me.GridView1.DataBind()
End Sub
C#
protected void Page_Load(object sender, EventArgs e)
{
MoviesDataContext dc = new MoviesDataContext();
var query = from m in dc.AllMovies
select m;
System.Diagnostics.Debug.WriteLine(query);
this.GridView1.DataSource = query;
this.GridView1.DataBind();
}
Unlike Tables or Views, which LINQ to SQL exposes as properties, Stored Procedures can require param-
eters. Therefore, LINQ to SQL exposes from the data context object them as method calls, allowing you to
provide method parameter values which are translated by LINQ into store procedure parameters. Listing
2-28 shows a simple stored procedure you can use to retrieve a specific Genre from the database.
Listing 9-28: Simple SQL Stored procedure
CREATE PROCEDURE dbo.GetGenre
(
@id int
)
AS
SELECT * FROM Genre WHERE ID = @id
You can add a Stored Procedure to your LINQ to SQL designer just as you did the Tables and Views,
by dragging them from the Server Explorer onto the LINQ to SQL Classes design surface. If you expect

your stored procedure to return a collection of data from a table in your database, you should drop
the stored procedure onto the LINQ class that represents the types returned by the query. In the case
of the stored procedure shown in Listing 9-28, it will return all of the Genre records that match the
provided ID, therefore you should drop the GetGenres stored procedure onto the Genres table in the
Visual Studio designer. This tells the designer to generate a method which returns a generic collection of
Genre objects. Once you drop the stored procedure onto the design surface, unlike the Tables and Views,
488
Evjen c09.tex V2 - 01/28/2008 2:09pm Page 489
Chapter 9: Querying with LINQ
the Stored Procedure will be displayed in a list on the right-hand side of the design surface. The GetGenre
stored procedure is shown after being added in Figure 9-13.
Figure 9-13 The GetGenre stored procedure has been added to the Method Pane in the LINQ to SQL
design surface
After you have added the Stored Proceedures, you can access them through the data context, just
as the Table and Views we accessed. As was stated earlier, however, LINQ to SQL exposes them
as method calls. Therefore, they may require you to provide method parameters, as shown in
Listing 9-29.
Listing 9-29: Selecting data from a Stored Procedure
VB
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs)
Dim dc As New MoviesDataContext()
Me.GridView1.DataSource = dc.GetGenre(1)
Me.GridView1.DataBind()
End Sub
Continued
489
Evjen c09.tex V2 - 01/28/2008 2:09pm Page 490
Chapter 9: Querying with LINQ
C#
protected void Page_Load(object sender, EventArgs e)

{
MoviesDataContext dc = new MoviesDataContext();
this.GridView1.DataSource = dc.GetGenre(1);
this.GridView1.DataBind();
}
Insert, Update, and Delete Queries through LINQ
Not only can LINQ to SQL be used to create powerful queries that select data from a data source, but it
can also manage insert, updates, and delete operations. By default, LINQ to SQL does this in much the
same manner as selecting data. LINQ to SQL uses the object class representations of the SQL structures
and dynamically generates SQL Insert, Update, and Delete commands. As with selection, you can also
use Stored Procedures to perform the insert, update, or deletes.
Insert Data Using LINQ
Inserting data using LINQ to SQL is as easy as creating a new instance of the object you want to insert,
and adding that to the object collection. The LINQ classes provide two methods called InsertOnSubmit
and InsertAllOnSubmit which make it simple to create and add any object to a LINQ collection. The
InsertOnSubmit accepts a single entity as its method parameter, allowing you to insert a single entity,
while the InsertAllOnSubmit method accepts a collection as its method parameter, allowing you to insert
an entire collection of data in a single method call.
Once you have added your objects, LINQ to SQL does require the extra step of calling the Data Context
objects SubmitChanges method. Calling this method tells LINQ to initiate the Insert action. Listing 9-30
shows an example of creating a new Movies object, and then Adding it to the Movies collection and
calling SubmitChanges to persist the change back to the SQL database.
Listing 9-30: Inserting data using LINQ to SQL
VB
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs)
Dim dc As New MoviesDataContext()
Dim m As New Movie With {.Title = "The Princess Bride", .Director =
"Rob Reiner", _
.Genre = 0, .ReleaseDate = DateTime.Parse("9/25/1987"), .Runtime = 98}
dc.Movies.InsertOnSubmit(m)

dc.SubmitChanges()
End Sub
C#
protected void Page_Load(object sender, EventArgs e)
490
Evjen c09.tex V2 - 01/28/2008 2:09pm Page 491
Chapter 9: Querying with LINQ
{
MoviesDataContext dc = new MoviesDataContext();
Movie m = new Movie { Title="The Princess Bride", Director="Rob Reiner", Genre=0,
ReleaseDate=DateTime.Parse("9/25/1987"), Runtime=98 } ;
dc.Movies.InsertOnSubmit(m);
dc.SubmitChanges();
}
Using Stored Procedures to Insert Data
Of course, you may already have a complex stored procedure written to handle the insertion of data into
your database table. LINQ makes it simple to use an existing Stored Procedure to insert data into a table.
To do this, on the LINQ to SQL design surface, select the entity you want to insert data into, which in this
case is the Movies entity. After selecting the entity, open its properties window and locate the Default
Methods section, as shown in Figure 9-14.
Figure 9-14 The properties of the Movies Default Methods section enable you to configure the Delete,
Insert, and Update behavior of LINQ to SQL for this table
491
Evjen c09.tex V2 - 01/28/2008 2:09pm Page 492
Chapter 9: Querying with LINQ
The Default Methods section contains three properties, Delete, Insert, and Update, which define the
behavior LINQ should use when executing these actions on the Movies table. By default, each property
is set to the value
UseRuntime
, which tells LINQ to dynamically generate SQL statements at runtime.

Because you want to insert data into the table using a Stored Procedure, open the Insert properties Con-
figure Behavior dialog.
In the dialog, change the Behavior radio button selection from Use Runtime to Customize. Next, select
the appropriate stored procedure from the drop-down list below the radio buttons. When you select the
stored procedure, LINQ automatically tries to match the table columns to the stored procedure input
parameters. However, you can change these manually, if needed.
The final Configure Behavior dialog is shown in Figure 9-15.
Figure 9-15 Configure Behavior dialog configured for the InsertMovie Stored Procedure
492
Evjen c09.tex V2 - 01/28/2008 2:09pm Page 493
Chapter 9: Querying with LINQ
Now, when you run the code from Listing 9-30, LINQ will use the stored procedure you configured
instead of dynamically generating a SQL Insert statement.
Update Data using LINQ
Updating data with LINQ is very similar to inserting data. The first set is to get the specific object you
want to update. You can do this by using the Single method of the collection you want to change. The
scalar Single method returns a single object from the collection based on its input parameter. If more than
one record matches the parameters, the Single method simply returns the first match.
Once you have the record you want to update, you simply change the object’s property values, and then
call the data context’s SubmitChanges method. Listing 9-31 shows the code required to update a specific
Movie.
Listing 9-31: Updating data using LINQ to SQL
VB
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs)
Dim dc As New MoviesDataContext()
Dim movie = dc.Movies.Single(Function(m) m.Title = "Fletch")
movie.Genre = 1
dc.SubmitChanges()
End Sub
C#

protected void Page_Load(object sender, EventArgs e)
{
MoviesDataContext dc = new MoviesDataContext();
var movie = dc.Movies.Single(m => m.Title == "Fletch");
movie.Genre = 1;
dc.SubmitChanges();
}
Handling Data Concurrency
LINQ to SQL also includes and uses by default optimistic concurrency. That means that if two users
retrieve the same record from the database and both try to update it, the first user to submit their update
to the server wins. If the second user attempts to update the record after the first, LINQ to SQL will detect
that the original record has changed and will raise a ChangeConflictException.
Deleting Data Using LINQ
Finally, LINQ to SQL also enables you to delete data from your SQL data source. Each data class object
generated by the LINQ to SQL designer also includes two methods that enable you to delete objects
from the collection, the
DeleteOnSubmit
and
DeleteAllOnSubmit
methods. As the names imply, the
DeleteOnSubmit
method removes a single object from the collection, whereas the
DeleteAllOnSubmit
method removes all records from the collection.
493
Evjen c09.tex V2 - 01/28/2008 2:09pm Page 494
Chapter 9: Querying with LINQ
Listing 9-32 shows how you can use LINQ and the
DeleteOnSubmit
and

DeleteAllOnSubmit
methods to
delete data from your data source.
Listing 9-32: Deleting data using LINQ to SQL
VB
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs)
Dim dc As New MoviesDataContext()
’Select and remove all Action movies
Dim query = From m In dc.Movies _
Where (m.Genre = 2) _
Select m
dc.Movies.DeleteAllOnSubmit(query)
’Select a single movie and remove it
Dim movie = dc.Movies.Single(Function(m) m.Title = "Fletch")
dc.Movies.DeleteOnSubmit(movie)
dc.SubmitChanges()
End Sub
C#
protected void Page_Load(object sender, EventArgs e)
{
MoviesDataContext dc = new MoviesDataContext();
//Select and remove all Action movies
var query = from m in dc.Movies
where m.Genre == 2
select m;
dc.Movies.DeleteAllOnSubmit(query);
//Select a single movie and remove it
var movie = dc.Movies.Single(m => m.Title == "Fletch");
dc.Movies.DeleteOnSubmit(movie);
dc.SubmitChanges();

}
As with the other SQL commands, you must remember to call the Data Contexts
SubmitChanges
method
in order to commit the changes back to the SQL data source.
Extending LINQ
This chapter focuses primarily on the LINQ capabilities included in the .NET framework, but LINQ is
highly extensible and can be used to create query frameworks over just about any data source. While
showing you how to implement you own LINQ provider is beyond the scope of this chapter, there are
lots of implementations of LINQ that query a wide variety of data stores such as LDAP, Sharepoint, and
even
Amazon.com.
494
Evjen c09.tex V2 - 01/28/2008 2:09pm Page 495
Chapter 9: Querying with LINQ
Roger Jennings from Oakleaf Systems maintains a list of third-party LINQ providers on his blog which
can be found at
/>.
Summary
This chapter has introduced you to the new Language Integrated Query, or LINQ, features of .NET 3.5,
which greatly simplifies the querying of data in .NET. LINQ makes query a first class concept, embedded
directly in .NET.
In this review of LINQ, we first looked at the current methods for performing object queries, including
basic data filtering, grouping, and sorting. We looked at the shortcomings of current object query tech-
niques, including the requirement for developers to not only define what the query should do, but also
exactly how it should do it. Additionally, we looked at how even simple operations can result in highly
complex code that can be difficult to read and maintain.
Next, we began looking at the three basic types of LINQ — LINQ to Objects, LINQ to XML, and LINQ
to SQL. Each flavor of LINQ uses the same basic query syntax to dramatically simplify the querying
of Objects, XML or SQL. We looked at how you can use the basic SQL-like query syntax for selection,

filtering, and grouping. This query syntax is clean and easily readable, and also includes many of the
same operator features as SQL.
We also looked at the basic O/R mapper that is included with LINQ to SQL. The O/R mapper makes it
easy to create CLR objects that represent SQL structures such as Tables, Views, and Stored Procedures.
Once the CLR objects are created, LINQ can be used to query the objects.
Finally we looked at how using LINQ to SQL, you can easily change the data in your database, using
generated SQL statements, or using custom Stored Procedures.
495

×