1. Trang chủ
  2. » Công Nghệ Thông Tin

Professional ASP.NET 3.5 in C# and Visual Basic Part 52 ppsx

10 411 0
Tài liệu đã được kiểm tra trùng lặp

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

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 10
Dung lượng 279,41 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

Next, the code uses a very simple LINQ query to select all of the Movie objects from the generic moviescollection.. Listing 9-7: Creating a custom projection with LINQ VB Protected Sub P

Trang 1

Next, the code uses a very simple LINQ query to select all of the Movie objects from the generic movies

collection Notice that this specific LINQ query utilizes new language keywords likefromandselect

in the query statement These syntax additions are first class members of the NET languages, therefore

Visual Studio 2008 can offer you development assistance such as strong type checking and IntelliSense,

making it easier for you to find and fix problems in your code

The query also defines a new variablem This variable is used in two ways in the query First, by defining

it in thefromstatement fromm, we are telling LINQ to makemrepresent the individual collection item,

which in this case is aMovieobject Telling LINQ this enables it to understand the structure of the objects

we are querying, and as you will see later, also gives us IntelliSense to help create the query

The second use ofmin the query is in theselectstatement Usingmin theselectstatement tells LINQ

to output a projection that matches the structure ofm In this case that means LINQ creates a projection

that matches theMovieobject structure

We could just have easily created our own custom projection by explicitly defining the fields we wanted

returned from the query using the new keyword along with the select operator This is shown below in

Listing 9-7

Listing 9-7: Creating a custom projection with LINQ

VB

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs)

Dim movies = GetMovies()

Dim query = From m In movies _

Select New With {m.Title, m.Genre}

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 new { m.Title, m.Genre };

this.GridView1.DataSource = query;

this.GridView1.DataBind();

}

Notice that rather than simply selectingm, we have defined a new projection containing only the Title

and Genre values

You can even go so far as to explicitly define the field names that the objects in the resultset will expose

For example, you may want to more explicitly name the Title and Genre fields to more fully describe

their contents Using LINQ, it’s easy to do this, as shown in Listing 9-8

Trang 2

Listing 9-8: Creating custom projection field names

VB

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs)

Dim movies = GetMovies()

Dim query = From m In movies _

Select New With {.MovieTitle = m.Title, MovieGenre = m.Genre}

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 new { MovieTitle = m.Title, MovieGenre = m Genre };

this.GridView1.DataSource = query;

this.GridView1.DataBind();

}

This sample explicitly defined the Fields that will be exposed by the resultset as MovieTitle and

MovieGenre You can see in Figure 9-1, that because of this change, the column headers in the

GridView have changed to match

Figure 9-1 Customized GridView column headers as the result of the LINQ projection

467

Trang 3

Finally the code binds the GridView control to the enumerable list of Movie object returned by the LINQ

query

As shown in Figure 9-2, running the code from Listing 9-6 results in the same vanilla Web page as the

one generated by Listing 9-2

Figure 9-2 The results of a basic LINQ query bound to a GridView control

LINQ also includes the ability to order the results using the order by statement As with SQL you can

choose to order the results in either ascending or descending order, as shown in Listing 9-9

Listing 9-9: Controlling data ordering using LINQ

VB

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs)

Dim movies = GetMovies()

Dim query = From m In movies _

Order By m.Title Descending _ Select New With {.MovieTitle = m.Title, MovieGenre = m.Genre}

Me.GridView1.DataSource = query

Me.GridView1.DataBind()

End Sub

C#

protected void Page_Load(object sender, EventArgs e)

{

var movies = GetMovies();

Trang 4

var query = from m in movies

orderby m.Title descending select new { MovieTitle = m.Title, MovieGenre = m Genre };

this.GridView1.DataSource = query;

this.GridView1.DataBind();

}

Another great feature of the new LINQ syntax is the dramatic improvement in readability and

under-standability that it makes in your code LINQ enables you to simply express the intention of your query, indicating to the compiler what you want your code to do, but leaving it up to the compiler to best

determine how it should be done

While these new keywords are what enable you to construct LINQ queries using a simple and clear

SQL-like syntax, rest assured there is no magic occurring These keywords actually map to extension

methods on the Movies collection You could actually write the same LINQ query directly using these

extension methods and it would look like this:

VB

Dim query = movies.Select( Function(m as Movie) m )

C#

var query = movies.Select(m => m);

This is what the compiler translates the keyword syntax into during its compilation process You may be

wondering how theSelectmethod got added to our genericList<Movies> collection because if you

look at the object structure ofList<T> , there is noSelectmethod LINQ adds theSelectmethod,

and many other methods it uses to the base Enumerable class, using Extension Methods Therefore, any

class that implements IEnumerable will be extended by LINQ with these methods You can see all of the

methods added by LINQ by right-clicking on theSelectmethod in Visual Studio and choosing the View

Definition option from the context menu Doing this causes Visual Studio to display the class metadata

for LINQ’sEnumerableclass If you scroll through this class, you will see not onlySelect, but other

methods such asWhere,Count,Min,Max, and many other methods that LINQ automatically adds to

any object that implements the IEnumerable interface.

Delayed Execution

An interesting feature of LINQ is its delayed execution behavior This means that even though you may execute the query statements at a specific point in your code, LINQ is smart enough to delay the actual execution of the query until it is accessed For example, in the previous samples, although the LINQ

query was written before the binding of the GridView controls, LINQ will not actually execute the query

we have defined until the GridView control begins to enumerate through the query results

Query Filters

LINQ also supports adding query filters using a familiar SQL-likewheresyntax You can modify the

LINQ query from Listing 9-3 to add filtering capabilities by adding awhereclause to the query, as shown

in Listing 9-10

469

Trang 5

Listing 9-10: Adding a filter to a LINQ query

VB

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs)

Dim movies = GetMovies()

Dim query = From m In movies _

Where m.Genre = 0 _ 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

where m.Genre==0 select m;

this.GridView1.DataSource = query;

this.GridView1.DataBind();

}

By adding this simplewhereclause to the LINQ query, the results returned by the query are filtered to

show movies from the 0 genre only, as shown in Figure 9-3

Figure 9-3 A filtered list of Movies

Also, notice that, because LINQ is a first-class member of NET, Visual Studio is able to provide an

Trang 6

whereclause, Visual Studio gives you IntelliSense for the possible parameters ofm(the Movie object), as shown in Figure 9-4

Figure 9-4 Because LINQ is a first class language concept, Visual Studio can give you Intellisense

Thewhereclause in LINQ behaves similarly to the SQLwhereclause, enabling you to include sub-queries and multiple where clauses, as shown in Listing 9-11

Listing 9-11: Adding a Where clause to a LINQ query

VB

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs)

Dim movies = GetMovies()

Dim query = From m In movies _

Where m.Genre = 0 And m.Runtime > 92 _ 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

where m.Genre == 0 && m.RunTime > 92 select m;

this.GridView1.DataSource = query;

this.GridView1.DataBind();

}

In this sample, thewhereclause includes two parameters, one restricting the movie genre, the other

restricting the movie’s runtime

471

Trang 7

Data Grouping

LINQ also greatly simplifies grouping data, again using a SQL-likegroupsyntax To show how easy

LINQ makes this, you can modify the original Listing 9-4 to use a LINQ query The modified code is

shown in Listing 9-12

Listing 9-12: Grouping data using a LINQ query

VB

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs)

Dim movies = GetMovies()

Dim query = From m In movies _

Group By m.Genre Into g = Group, Count() 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

group m by m.Genre into g select new { Genre = g.Key, Count = g.Count() };

this.GridView1.DataSource = query;

this.GridView1.DataBind();

}

This LINQ query uses thegroupkeyword to group the movie data by genre Additionally, because a

group action does not naturally result in any output, the query creates a custom query projection using

the techniques discussed earlier The results of this query are shown in Figure 9-5

Trang 8

Using LINQ to do this allows you to significantly reduce the lines of code required If we compare the

amount of code required to perform the grouping action in Listing 9-4, with the previous listing using

LINQ, you can see that the number of lines of code has dropped from 18 to 3, and the readability and

clarity of the code has improved

Other LINQ Operators

Besides basic selection, filtering and grouping, LINQ also includes many operators you can execute on

enumerable objects Most of these operators are available for you to use and are similar to operators you find in SQL, such as Count, Min, Max, Average, and Sum, as shown in Listing 9-13

Listing 9-13: Using LINQ query operators

VB

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs)

Dim movies = GetMovies()

Me.TotalMovies.Text = movies.Count.ToString()

Me.LongestRuntime.Text = movies.Max(Function(m) m.Runtime).ToString()

Me.ShortestRuntime.Text = movies.Min(Function(m) m.Runtime).ToString()

Me.AverageRuntime.Text = movies.Average(Function(m) m.Runtime).ToString()

End Sub

C#

protected void Page_Load(object sender, EventArgs e)

{

var movies = GetMovies();

this.TotalMovies.Text = movies.Count.ToString();

this.LongestRuntime.Text = movies.Max(m => m.RunTime).ToString();

this.ShortestRuntime.Text = movies.Min(m => m.RunTime).ToString();

this.AverageRuntime.Text = movies.Average(m => m.RunTime).ToString();

}

This listing demonstrates the use of the Count, Max, Min, and Average operators with the movies collec-tion Notice that for all but the Count operator, you need to provide the method with the specific field

you want to execute the operation on This is done using a Lambda expression

LINQ Joins

LINQ also supports the unioning of data from different collections using a familiar SQL-like join syntax For example, in our sample data thus far, we have only been able to display the Genre as a numeric ID

It would be preferable to actually display the name of each Genre instead To do this, you simply create

a Genre class, which defines the properties of the genre, as shown in Listing 9-14

Listing 9-14: A simple Genre class

VB

Public Class Genre

Private _id As Integer

Private _name As String

Continued

473

Trang 9

Public Property ID() As Integer

Get Return _id End Get Set(ByVal value As Integer) _id = value

End Set End Property

Public Property Name() As String

Get Return _name End Get

Set(ByVal value As String) _name = value

End Set End Property

End Class

C#

public class Genre

{

public int ID { get; set; }

public string Name { get; set; }

}

Next you can add aGetGenresmethod to your Web page that returns a list of Genre objects, as shown in

Listing 9-15

Listing 9-15: Populating a collection of Genres

VB

Public Function GetGenres() As List(Of Genre)

Dim genres As Genre() = { _

New Genre With {.ID = 0, Name = "Comedy"}, _ New Genre With {.ID = 1, Name = "Drama"}, _ New Genre With {.ID = 2, Name = "Action"} _ }

Return New List(Of Genre)(genres)

End Function

C#

public List<Genre> GetGenres()

{

return new List<Genre> {

new Genre { ID=0, Name="Comedy" } , new Genre { ID=1, Name="Drama" } , new Genre { ID=2, Name="Action" } };

}

Trang 10

Finally, you can modify the Page Load event, including the LINQ query, to retrieve the Genres list and, using LINQ, join that to the Movies list This is shown in Listing 9-16

Listing 9-16: Joining Genre data with Movie data using a LINQ query

VB

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs)

Dim movies = GetMovies()

Dim genres = GetGenres()

Dim query = From m In movies Join g In genres _

On m.Genre Equals g.ID _ Select New With {.Title = m.Title, Genre = g.Name}

GridView1.DataSource = query

GridView1.DataBind()

End Sub

C#

protected void Page_Load(object sender, EventArgs e)

{

var movies = GetMovies();

var genres = GetGenres();

var query = from m in movies

join g in genres on m.Genre equals g.ID select new { m.Title, Genre = g.Name } ; this.GridView1.DataSource = query;

this.GridView1.DataBind();

}

As you can see in this sample, the join syntax is relatively simple You tell LINQ to include the genres

object, and then tell LINQ which fields it should associate

Paging Using LINQ

LINQ also makes it much easier to include paging logic in your Web application by exposing theSkip

andTakemethods TheSkipmethod enables you to skip a defined number of records in the resultset

TheTakemethod enables you to specify the number of records to return from the resultset By calling

Skip, and thenTake, you can return a specific number of records from a specific location of the resultset This is shown in Listing 9-17

Listing 9-17: Simple Paging using LINQ methods

VB

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs)

Dim movies = GetMovies()

Dim genres = GetGenres()

Dim query = (From m In movies _

Join g In genres On m.Genre Equals g.ID _

Continued

475

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

TỪ KHÓA LIÊN QUAN