Professional ASP.NET 3.5 in C# and Visual Basic Part 51 doc

10 296 0
Professional ASP.NET 3.5 in C# and Visual Basic Part 51 doc

Đang tải... (xem toàn văn)

Thông tin tài liệu

Evjen c09.tex V2 - 01/28/2008 2:09pm Page 456 Chapter 9: Querying with LINQ Listing 9-1: A basic Movie class VB Imports Microsoft.VisualBasic Public Class Movie Private _title As String Private _director As String Private _genre As Integer Private _runtime As Integer Private _releasedate As DateTime Public Property Title() As String Get Return _title End Get Set(ByVal value As String) _title = value End Set End Property Public Property Director() As String Get Return _director End Get Set(ByVal value As String) _director = value End Set End Property Public Property Genre() As Integer Get Return _genre End Get Set(ByVal value As Integer) _genre = value End Set End Property Public Property Runtime() As Integer Get Return _runtime End Get Set(ByVal value As Integer) _runtime = value End Set End Property Public Property ReleaseDate() As DateTime Get Return _releasedate End Get Set(ByVal value As DateTime) 456 Evjen c09.tex V2 - 01/28/2008 2:09pm Page 457 Chapter 9: Querying with LINQ _releasedate = value End Set End Property End Class C# using System; public class Movie { public string Title { get; set; } public string Director { get; set; } public int Genre { get; set; } public int RunTime { get; set; } public DateTime ReleaseDate { get; set; } } This is the basic class that is used throughout this section and the following LINQ to Object section. Now that you have a basic class to work with, let’s look at how you would normally use the class. Listing 9-2 demonstrates how to create a simple generic List of the Movie objects in an ASP.NET page, and then binding that list to a GridView control. The GridView displays the values of all public properties exposed by the Movie class. Listing 9-2: Generating a list of Movie objects and binding to a GridView VB <%@ Page Language="VB" %> <%@ Import Namespace="System.Collections.Generic" %> <script runat="server"> Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Dim movies = GetMovies() Me.GridView1.DataSource = movies Me.GridView1.DataBind() End Sub Public Function GetMovies() As List(Of Movie) Dim movies As Movie() = { _ New Movie With {.Title = "Shrek", .Director = "Andrew Adamson", _ .Genre = 0, .ReleaseDate = DateTime.Parse("5/16/2001"), .Runtime = 89}, _ New Movie With {.Title = "Fletch", .Director = "Michael Ritchie", _ .Genre = 0, .ReleaseDate = DateTime.Parse("5/31/1985"), .Runtime = 96}, _ New Movie With {.Title = "Casablanca", .Director = "Michael Curtiz", _ .Genre = 1, .ReleaseDate = DateTime.Parse("1/1/1942"), .Runtime = 102}, _ New Movie With {.Title = "Batman", .Director = "Tim Burton", _ .Genre = 1, .ReleaseDate = DateTime.Parse("6/23/1989"), .Runtime = 126}, _ Continued 457 Evjen c09.tex V2 - 01/28/2008 2:09pm Page 458 Chapter 9: Querying with LINQ New Movie With {.Title = "Dances with Wolves", .Director = "Kevin Costner", _ .Genre = 1, .ReleaseDate = DateTime.Parse("11/21/1990"), .Runtime = 180}, _ New Movie With {.Title = "Dirty Dancing", .Director = "Emile Ardolino", _ .Genre = 1, .ReleaseDate = DateTime.Parse("8/21/1987"), .Runtime = 100}, _ New Movie With {.Title = "The Parent Trap", .Director = "Nancy Meyers", _ .Genre = 0, .ReleaseDate = DateTime.Parse("7/29/1998"), .Runtime = 127}, _ New Movie With {.Title = "Ransom", .Director = "Ron Howard", _ .Genre = 1, .ReleaseDate = DateTime.Parse("11/8/1996"), .Runtime = 121}, _ New Movie With {.Title = "Ocean’s Eleven", .Director = "Steven Soderbergh", _ .Genre = 1, .ReleaseDate = DateTime.Parse("12/7/2001"), .Runtime = 116}, _ New Movie With {.Title = "Steel Magnolias", .Director = "Herbert Ross", _ .Genre = 1, .ReleaseDate = DateTime.Parse("11/15/1989"), .Runtime = 117}, _ New Movie With {.Title = "Mystic Pizza", .Director = "Donald Petrie", _ .Genre = 1, .ReleaseDate = DateTime.Parse("10/21/1988"), .Runtime = 104}, _ New Movie With {.Title = "Pretty Woman", .Director = "Garry Marshall", _ .Genre = 1, .ReleaseDate = DateTime.Parse("3/23/1990"), .Runtime = 119}, _ New Movie With {.Title = "Interview with the Vampire", .Director = "Neil Jordan", _ .Genre = 1, .ReleaseDate = DateTime.Parse("11/11/1994"), .Runtime = 123}, _ New Movie With {.Title = "Top Gun", .Director = "Tony Scott", _ .Genre = 2, .ReleaseDate = DateTime.Parse("5/16/1986"), .Runtime = 110}, _ New Movie With {.Title = "Mission Impossible", .Director = "Brian De Palma", _ .Genre = 2, .ReleaseDate = DateTime.Parse("5/22/1996"), .Runtime = 110}, _ New Movie With {.Title = "The Godfather", .Director = "Francis Ford Coppola", _ .Genre = 1, .ReleaseDate = DateTime.Parse("3/24/1972"), .Runtime = 175}, _ New Movie With {.Title = "Carlito’s Way", .Director = "Brian De Palma", _ .Genre = 1, .ReleaseDate = DateTime.Parse("11/10/1993"), .Runtime = 144}, _ New Movie With {.Title = "Robin Hood: Prince of Thieves", _ .Director = "Kevin Reynolds", .Genre = 1, _ .ReleaseDate = DateTime.Parse("6/14/1991"), .Runtime = 143}, _ New Movie With {.Title = "The Haunted", .Director = "Robert Mandel", _ .Genre = 1, .ReleaseDate = DateTime.Parse("5/6/1991"), .Runtime = 100}, _ New Movie With {.Title = "Old School", .Director = "Todd Phillips", _ .Genre = 0, .ReleaseDate = DateTime.Parse("2/21/2003"), .Runtime = 91}, _ New Movie With {.Title = "Anchorman: The Legend of Ron Burgundy", _ Continued 458 Evjen c09.tex V2 - 01/28/2008 2:09pm Page 459 Chapter 9: Querying with LINQ .Director = "Adam McKay", .Genre = 0, _ .ReleaseDate = DateTime.Parse("7/9/2004"), .Runtime = 94}, _ New Movie With {.Title = "Bruce Almighty", .Director = "Tom Shadyac", _ .Genre = 0, .ReleaseDate = DateTime.Parse("5/23/2003"), .Runtime = 101}, _ New Movie With {.Title = "Ace Ventura: Pet Detective", _ .Director = "Tom Shadyac", .Genre = 0, _ .ReleaseDate = DateTime.Parse("2/4/1994"), .Runtime = 86}, _ New Movie With {.Title = "Goonies", .Director = "Richard Donner", _ .Genre = 0, .ReleaseDate = DateTime.Parse("6/7/1985"), .Runtime = 114}, _ New Movie With {.Title = "Sixteen Candles", .Director = "John Hughes", _ .Genre = 1, .ReleaseDate = DateTime.Parse("5/4/1984"), .Runtime = 93}, _ New Movie With {.Title = "The Breakfast Club", .Director = "John Hughes", _ .Genre = 1, .ReleaseDate = DateTime.Parse("2/15/1985"), .Runtime = 97}, _ New Movie With {.Title = "Pretty in Pink", .Director = "Howard Deutch", _ .Genre = 1, .ReleaseDate = DateTime.Parse("2/28/1986"), .Runtime = 96}, _ New Movie With {.Title = "Weird Science", .Director = "John Hughes", _ .Genre = 0, .ReleaseDate = DateTime.Parse("8/2/1985"), .Runtime = 94}, _ New Movie With {.Title = "Breakfast at Tiffany’s", .Director = "Blake Edwards", _ .Genre = 1, .ReleaseDate = DateTime.Parse("10/5/1961"), .Runtime = 115}, _ New Movie With {.Title = "The Graduate", .Director = "Mike Nichols", _ .Genre = 1, .ReleaseDate = DateTime.Parse("4/2/1968"), .Runtime = 105}, _ New Movie With {.Title = "Dazed and Confused", .Director = "Richard Linklater", _ .Genre = 0, .ReleaseDate = DateTime.Parse("9/24/1993"), .Runtime = 103}, _ New Movie With {.Title = "Arthur", .Director = "Steve Gordon", _ .Genre = 1, .ReleaseDate = DateTime.Parse("9/25/1981"), .Runtime = 97}, _ New Movie With {.Title = "Monty Python and the Holy Grail", _ .Director = "Terry Gilliam", .Genre = 0, _ .ReleaseDate = DateTime.Parse("5/10/1975"), .Runtime = 91}, _ New Movie With {.Title = "Dirty Harry", .Director = "Don Siegel", _ .Genre = 2, .ReleaseDate = DateTime.Parse("12/23/1971"), .Runtime = 102} _ } Return New List(Of Movie)(movies) End Function </script> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> Continued 459 Evjen c09.tex V2 - 01/28/2008 2:09pm Page 460 Chapter 9: Querying with LINQ <title>My Favorite Movies</title> </head> <body> <form id="form1" runat="server"> <div> <asp:GridView ID="GridView1" runat="server"> </asp:GridView> </div> </form> </body> </html> C# <script runat="server"> protected void Page_Load(object sender, EventArgs e) { var movies = GetMovies(); this.GridView1.DataSource = movies; this.GridView1.DataBind(); } public List<Movie> GetMovies() { return new List<Movie> { new Movie { Title="Shrek", Director="Andrew Adamson", Genre=0, ReleaseDate=DateTime.Parse("5/16/2001"), RunTime=89 } , new Movie { Title="Fletch", Director="Michael Ritchie", Genre=0, ReleaseDate=DateTime.Parse("5/31/1985"), RunTime=96 } , new Movie { Title="Casablanca", Director="Michael Curtiz", Genre=1, ReleaseDate=DateTime.Parse("1/1/1942"), RunTime=102 } , new Movie { Title="Batman", Director="Tim Burton", Genre=1, ReleaseDate=DateTime.Parse("6/23/1989"), RunTime=126 } , new Movie { Title="Dances with Wolves", Director="Kevin Costner",Genre=1, ReleaseDate=DateTime.Parse("11/21/1990"), RunTime=180 } , new Movie { Title="Dirty Dancing", Director="Emile Ardolino", Genre=1, ReleaseDate=DateTime.Parse("8/21/1987"), RunTime=100 } , new Movie { Title="The Parent Trap", Director="Nancy Meyers", Genre=0, ReleaseDate=DateTime.Parse("7/29/1998"), RunTime=127 } , new Movie { Title="Ransom", Director="Ron Howard", Genre=1, ReleaseDate=DateTime.Parse("11/8/1996"), RunTime=121 } , new Movie { Title="Ocean’s Eleven", Director="Steven Soderbergh", Genre=1, ReleaseDate=DateTime.Parse("12/7/2001"), RunTime=116 } , new Movie { Title="Steel Magnolias", Director="Herbert Ross", Genre=1, ReleaseDate=DateTime.Parse("11/15/1989"), RunTime=117 } , new Movie { Title="Mystic Pizza", Director="Donald Petrie", Genre=1, ReleaseDate=DateTime.Parse("10/21/1988"), RunTime=104 } , new Movie { Title="Pretty Woman", Director="Garry Marshall", Genre=1, ReleaseDate=DateTime.Parse("3/23/1990"), RunTime=119 } , new Movie { Title="Interview with the Vampire", Director="Neil Jordan", Genre=1, ReleaseDate=DateTime.Parse("11/11/1994"), RunTime=123 } , Continued 460 Evjen c09.tex V2 - 01/28/2008 2:09pm Page 461 Chapter 9: Querying with LINQ new Movie { Title="Top Gun", Director="Tony Scott", Genre=2, ReleaseDate=DateTime.Parse("5/16/1986"), RunTime=110 } , new Movie { Title="Mission Impossible", Director="Brian De Palma", Genre=2, ReleaseDate=DateTime.Parse("5/22/1996"), RunTime=110 } , new Movie { Title="The Godfather", Director="Francis Ford Coppola", Genre=1, ReleaseDate=DateTime.Parse("3/24/1972"), RunTime=175 } , new Movie { Title="Carlito’s Way", Director="Brian De Palma", Genre=1, ReleaseDate=DateTime.Parse("11/10/1993"), RunTime=144 } , new Movie { Title="Robin Hood: Prince of Thieves", Director="Kevin Reynolds", Genre=1, ReleaseDate=DateTime.Parse("6/14/1991"), RunTime=143 } , new Movie { Title="The Haunted", Director="Robert Mandel", Genre=1, ReleaseDate=DateTime.Parse("5/6/1991"), RunTime=100 } , new Movie { Title="Old School", Director="Todd Phillips", Genre=0, ReleaseDate=DateTime.Parse("2/21/2003"), RunTime=91 } , new Movie { Title="Anchorman: The Legend of Ron Burgundy", Director="Adam McKay", Genre=0, ReleaseDate=DateTime.Parse("7/9/2004"), RunTime=94 } , new Movie { Title="Bruce Almighty", Director="Tom Shadyac", Genre=0, ReleaseDate=DateTime.Parse("5/23/2003"), RunTime=101 } , new Movie { Title="Ace Ventura: Pet Detective", Director="Tom Shadyac", Genre=0, ReleaseDate=DateTime.Parse("2/4/1994"), RunTime=86 } , new Movie { Title="Goonies", Director="Richard Donner", Genre=0, ReleaseDate=DateTime.Parse("6/7/1985"), RunTime=114 } , new Movie { Title="Sixteen Candles", Director="John Hughes", Genre=1, ReleaseDate=DateTime.Parse("5/4/1984"), RunTime=93 } , new Movie { Title="The Breakfast Club", Director="John Hughes", Genre=1, ReleaseDate=DateTime.Parse("2/15/1985"), RunTime=97 } , new Movie { Title="Pretty in Pink", Director="Howard Deutch", Genre=1, ReleaseDate=DateTime.Parse("2/28/1986"), RunTime=96 } , new Movie { Title="Weird Science", Director="John Hughes", Genre=0, ReleaseDate=DateTime.Parse("8/2/1985"), RunTime=94 } , new Movie { Title="Breakfast at Tiffany’s", Director="Blake Edwards", Genre=1, ReleaseDate=DateTime.Parse("10/5/1961"), RunTime=115 } , new Movie { Title="The Graduate", Director="Mike Nichols", Genre=1, ReleaseDate=DateTime.Parse("4/2/1968"), RunTime=105 } , new Movie { Title="Dazed and Confused", Director="Richard Linklater", Genre=0, ReleaseDate=DateTime.Parse("9/24/1993"), RunTime=103 } , new Movie { Title="Arthur", Director="Steve Gordon", Genre=1, ReleaseDate=DateTime.Parse("9/25/1981"), RunTime=97 } , new Movie { Title="Monty Python and the Holy Grail", Director="Terry Gilliam", Genre=0, ReleaseDate=DateTime.Parse("5/10/1975"), RunTime=91 } , new Movie { Title="Dirty Harry", Director="Don Siegel", Genre=2, ReleaseDate=DateTime.Parse("12/23/1971"), RunTime=102 } }; } </script> Running the sample generates a typical ASP.NET Web page that includes a simple grid showing all of the Movie data on it. Now, what happens when you want to start performing queries on the list of movies? For example, you might want to filter this data to show only a specific genre of movie. Listing 9-3 shows a typical way you might perform this filtering. 461 Evjen c09.tex V2 - 01/28/2008 2:09pm Page 462 Chapter 9: Querying with LINQ Listing 9-3: Filtering the listing Movie objects VB Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Dim movies = GetMovies() Dim query As New List(Of Movie)() For Each m In movies If (m.Genre = 0) Then query.Add(m) End If Next Me.GridView1.DataSource = query Me.GridView1.DataBind() End Sub C# protected void Page_Load(object sender, EventArgs e) { var movies = GetMovies(); var query = new List<Movie>(); foreach (var m in movies) { if (m.Genre == 0) query.Add(m); } this.GridView1.DataSource = query; this.GridView1.DataBind(); } As this sample shows, to filter the data so that the page displays Movies in a specific genre only requires the creation of a new temporary collection and the use of a foreach loop to iterate through the data. While this technique seems easy enough, it still requires that you define what you want done (find all movies in the genre), and also that you explicitly define how it should be done (use a temporary collection and a foreach loop). Additionally, what happens when you need to perform more complex queries, involving grouping or sorting? Now the complexity of the code dramatically increases, as shown in Listing 9-4. Listing 9-4: Grouping and sorting the List of Movie objects VB Public Class Grouping Private _genre As Integer Private _movieCount As Integer Public Property Genre() As Integer Get Return _genre Continued 462 Evjen c09.tex V2 - 01/28/2008 2:09pm Page 463 Chapter 9: Querying with LINQ End Get Set(ByVal value As Integer) _genre = value End Set End Property Public Property MovieCount() As Integer Get Return _movieCount End Get Set(ByVal value As Integer) _movieCount = value End Set End Property End Class Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Dim movies = GetMovies() Dim groups As New Dictionary(Of String, Grouping) For Each m In movies If (Not groups.ContainsKey(m.Genre)) Then groups(m.Genre) = _ New Grouping With {.Genre = m.Genre, .MovieCount = 0} End If groups(m.Genre).MovieCount = groups(m.Genre).MovieCount + 1 Next Dim results As New List(Of Grouping)(groups.Values) results.Sort(AddressOf MovieSort) Me.GridView1.DataSource = results Me.GridView1.DataBind() End Sub Private Function MovieSort(ByVal x As Grouping, ByVal y As Grouping) As Integer Return IIf(x.MovieCount > y.MovieCount, -1, IIf(x.MovieCount < y.MovieCount, 1, 0)) End Function C# public class Grouping { public int Genre { get; set; } public int MovieCount { get; set; } } protected void Page_Load(object sender, EventArgs e) { var movies = GetMovies(); Continued 463 Evjen c09.tex V2 - 01/28/2008 2:09pm Page 464 Chapter 9: Querying with LINQ Dictionary<int, Grouping> groups = new Dictionary<int, Grouping>(); foreach (Movie m in movies) { if (!groups.ContainsKey(m.Genre)) { groups[m.Genre] = new Grouping { Genre = m.Genre, MovieCount = 0 }; } groups[m.Genre].MovieCount++; } List<Grouping> results = new List<Grouping>(groups.Values); results.Sort(delegate(Grouping x, Grouping y) { return x.MovieCount > y.MovieCount ? -1 : x.MovieCount < y.MovieCount ? 1 : 0; }); this.GridView1.DataSource = results; this.GridView1.DataBind(); } To group the Movie data into genres and count how many movies are in each genre requires the addition of a new class, the creation of a Dictionary, and the implementation of a delegate, all fairly complex requirements for such a seemingly simple task, and again, not only defining very specifically what you want done, but very explicitly how it should be done. Additionally, because the complexity of the code increases so much, it becomes quite difficult to actually determine what this code is doing. Consider this: What if you were asked to modify this code in an existing application that you were unfamiliar with? How long would it take you to figure out what it was doing? Replacing Traditional Queries with LINQ LINQ was created to address many of the shortcomings of querying collections of data that were dis- cussed in the previous section. Rather than requiring you to very specifically define exactly how you want a query to execute, LINQ gives you the power to stay at a more abstract level. By simply defining what you want the query to return, you leave it up to .NET and its compilers to determine the specifics of exactly how the query will be run. In the preceding section, you looked at the current state of object querying with today’s .NET languages. In this section, let’s take a look at LINQ and see how using it can greatly simplify these queries, as well as other types of queries. To do this, the samples in this section start out by simply modifying the samples from the previous section to show you how easy LINQ makes the same tasks. Before you get started, understand that LINQ is an extension to .NET, and because of this, is isolated in its own set of assemblies. The base LINQ functionality is located in the new System.Core.dll assem- bly. This assembly does not replace any existing framework functionality, but simply augments it. 464 Evjen c09.tex V2 - 01/28/2008 2:09pm Page 465 Chapter 9: Querying with LINQ Additionally, by default, projects in Visual Studio 2008 include a reference to this assembly so when starting a new ASP.NET Web project, LINQ should be readily available to you. Basic LINQ Queries and Projections In order to start modifying the prior sections samples to using LINQ queries, you first need to add the LINQ namespace to the Web page, as shown in Listing 9-5. Listing 9-5: Adding the LINQ namespace <%@ Import Namespace="System.Linq" %> Adding this namespace gives the page access to all of the basic LINQ functionality. If you are using the code-behind development model, then the LINQ namespace should already be included in your code-behind class. Note that the default web.config file included with a Visual Basic Web site already includes the Sys- tem.Linq namespace declaration in it, so if you are using this type of project you do not need to manually add the namespace. Next, you can start by modifying code from Listing 9-2. If you remember, this basic sample simply generates a generic List of movies and binds the list to a GridView control. Listing 9-6 shows how the code can be modified to use LINQ to query the movies list and bind the resultset to the GridView. Listing9-6:CreatingaquerywithLINQ VB Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Dim movies = GetMovies() Dim query = From m In movies _ Select m Me.GridView1.DataSource = query Me.GridView1.DataBind() End Sub C# protected void Page_Load(object sender, EventArgs e) { var movies = GetMovies(); var query = from m in movies select m; this.GridView1.DataSource = query; this.GridView1.DataBind(); } If we deconstruct the code sample, there are three basic actions happening. First, the code uses the Get- Movies() method to obtain the generic List < Movie > collection. 465 . 456 Chapter 9: Querying with LINQ Listing 9-1: A basic Movie class VB Imports Microsoft.VisualBasic Public Class Movie Private _title As String Private _director As String Private _genre As Integer Private. 2:09pm Page 4 65 Chapter 9: Querying with LINQ Additionally, by default, projects in Visual Studio 2008 include a reference to this assembly so when starting a new ASP. NET Web project, LINQ should. you. Basic LINQ Queries and Projections In order to start modifying the prior sections samples to using LINQ queries, you first need to add the LINQ namespace to the Web page, as shown in Listing

Ngày đăng: 05/07/2014, 18:20

Từ khóa liên quan

Tài liệu cùng người dùng

  • Đang cập nhật ...

Tài liệu liên quan