Retrieving Data from Multiple Tables with LINQ

Một phần của tài liệu Visual C 2012 How to Program _ www.bit.ly/taiho123 (Trang 915 - 920)

2. When the app executes, another compiler (known as the just-in-time compiler

22.7 Retrieving Data from Multiple Tables with LINQ

In this section, you’ll perform LINQ to Entities queries using the LINQ query syntax that was introduced in Chapter 9. In particular, you’ll learn how to obtain query results that combine data from multiple tables (Fig. 22.23).

Fig. 22.23 | Outputs from theJoining Tables with LINQapp. (Part 1 of 2.)

a) List of authors and the ISBNs of the books they’ve authored; sort the authors by last name then first name

b) List of authors and the titles of the book’s they’ve authored; sort the authors by last name then first name; for a given author, sort the titles alphabetically

22.7 Retrieving Data from Multiple Tables with LINQ 875

TheJoining Tables with LINQapp uses LINQ to Entities to combine and organize data from multiple tables, and shows the results of queries that perform the following tasks:

• Get a list of all the authors and the ISBNs of the books they’ve authored, sorted by last name then first name (Fig. 22.23(a)).

• Get a list of all the authors and the titles of the books they’ve authored, sorted by last name then first; for each author sort the titles alphabetically (Fig. 22.23(b)).

• Get a list of all the book titles grouped by author, sorted by last name then first;

for a given author sort the titles alphabetically (Fig. 22.23(c)).

GUI for theJoining Tables with LINQApp

For this example (Fig. 22.24–Fig. 22.27), perform the steps in Section 22.5.2 to create a newWindows Forms Applicationproject namedJoinQueriesin the same solution as the previous examples. Rename theForm1.cssource file to JoiningTableData.cs. Set the

Form’sTextproperty toJoining Tables with LINQ. Be sure to set theJoinQueriesproject as the startup project. We set the following properties for theoutputTextBox:

• Fontproperty: Set toLucida Consoleto display the output in a fixed-width font.

• Anchorproperty: Set toTop, Bottom, Left, Rightso that you can resize the win- dow and theoutputTextBoxwill resize accordingly.

• Scrollbarsproperty: Set toVertical, so that you can scroll through the output.

Creating theDbContext

The code uses the entity data model classes to combine data from the tables in theBooks database and display the relationships between the authors and books in three different ways. We split the code for classJoiningTableData into several figures (Figs. 22.24–

22.27) for presentation purposes. As in previous examples, the DbContext object (Fig. 22.24, lines 19–20) allows the program to interact with the database.

Fig. 22.23 | Outputs from theJoining Tables with LINQapp. (Part 2 of 2.)

c) List of titles grouped by author;

sort the authors by last name then first name; for a given author, sort the titles alphabetically

Combining Author Names with the ISBNs of the Books They’ve Written

The first query (Fig. 22.25, lines 24–27)joinsdata from two tables and returns a list of author names and the ISBNs representing the books they’ve written, sorted byLastName then FirstName. The query takes advantage of the properties in the entity data model classes that were created based on foreign-key relationships between the database’s tables.

These properties enable you to easily combine data from related rows in multiple tables.

1 // Fig. 22.24: JoiningTableData.cs

2 // Using LINQ to perform a join and aggregate data across tables.

3 using System;

4 using System.Linq;

5 using System.Windows.Forms;

6

7 namespace JoinQueries 8 {

9 public partial class JoiningTableData : Form

10 {

11 public JoiningTableData()

12 {

13 InitializeComponent();

14 } // end constructor 15

16 private void JoiningTableData_Load(object sender, EventArgs e)

17 {

18 // Entity Framework DbContext

19 BooksExamples.BooksEntities dbcontext = 20 new BooksExamples.BooksEntities();

21

Fig. 22.24 | Creating theBooksDataContextfor querying theBooksdatabase.

22 // get authors and ISBNs of each book they co-authored 23 var authorsAndISBNs =

24 25 26 27 28

29 outputTextBox.AppendText( "Authors and ISBNs:" );

30

31 // display authors and ISBNs in tabular format 32 foreach ( var element in authorsAndISBNs )

33 {

34 outputTextBox.AppendText(

35 String.Format( "\r\n\t{0,-10} {1,-10} {2,-10}",

36 element.FirstName, element.LastName, element.ISBN ) );

37 } // end foreach 38

Fig. 22.25 | Getting a list of authors and the ISBNs of the books they’ve authored.

from author in dbcontext.Authors from book in author.Titles

orderby author.LastName, author.FirstName

select new { author.FirstName, author.LastName, book.ISBN };

22.7 Retrieving Data from Multiple Tables with LINQ 877

The firstfromclause (line 24) gets eachauthorfrom theAuthorstable. The second

fromclause (line 25) uses the generatedTitlesproperty of theAuthorclass to get the ISBNs for the currentauthor. The entity data model uses the foreign-key information stored in the database’sAuthorISBNtable to get the appropriate ISBNs. The combined result of the twofromclauses is a collection of all the authors and the ISBNs of the books they’ve authored. The twofromclauses introducetworange variables into the scope of this query—other clauses can access both range variables to combine data from multiple tables.

Line 26 orders the results by theauthor’sLastName, thenFirstName. Line 27 creates a new anonymous type that contains theFirstNameandLastNameof anauthorfrom the

Authorstable with theISBNof abookin theTitlestable written by that author.

Anonymous Types

As you know, anonymous types allow you to create simple classes used to store data without writing a class definition. Ananonymous type declaration(line 27)—known formally as an anonymous object-creation expression—is similar to an object initializer (Section 10.13). The anonymous type declaration begins with the keywordnewfollowed by a member-initializer list in braces ({}). No class name is specified after thenewkeyword. The compiler generates a class definition based on the anonymous object-creation expression. This class contains the properties specified in the member-initializer list—FirstName, LastName and ISBN. All properties of an anonymous type arepublic. Anonymous type properties areread-only—you cannot modify a property’s value once the object is created. Each property’s type isinferred from the values assigned to it. The class definition is generated automatically by the compil- er, so you don’t know the class’s type name (hence the term anonymous type). Thus, you must useimplicitly typed local variablesto store references to objects of anonymous types (e.g., line 32). Though we are not using it here, the compiler defines aToStringmethod when creating the anonymous type’s class definition. The method returns astringin curly braces containing a comma-separated list ofPropertyName=valuepairs. The compiler also provides anEqualsmethod, which compares the properties of the anonymous object that calls the method and the anonymous object that it receives as an argument.

Combining Author Names with the Titles of the Books They’ve Written

The second query (Fig. 22.26, lines 41–45) gives similar output, but uses the foreign-key relationships to get the title of each book that an author wrote.

39 // get authors and titles of each book they co-authored 40 var authorsAndTitles =

41 42 43 44 45 46

47 outputTextBox.AppendText( "\r\n\r\nAuthors and titles:" );

48

49 // display authors and titles in tabular format 50 foreach ( var element in authorsAndTitles )

51 {

Fig. 22.26 | Getting a list of authors and the titles of the books they’ve authored. (Part 1 of 2.)

from book in dbcontext.Titles from author in book.Authors

orderby author.LastName, author.FirstName, book.Title1 select new { author.FirstName, author.LastName,

book.Title1 };

The firstfromclause (line 41) gets eachbookfrom theTitlestable. The secondfrom clause (line 42) uses the generated Authorsproperty of the Titleclass to get only the authors for the currentbook. The entity data model uses the foreign-key information stored in the database’s AuthorISBN table to get the appropriate authors. The author objects give us access to the names of the current book’s authors. Theselectclause (lines 44–45) uses theauthorandbookrange variables introduced earlier in the query to get the

FirstNameandLastNameof each author from theAuthorstable and the title of each book from theTitlestable.

Organizing Book Titles by Author

Most queries return results with data arranged in a relational-style table of rows and col- umns. The last query (Fig. 22.27, lines 60–66) returns hierarchical results. Each element in the results contains the name of anAuthorand a list ofTitles that the author wrote.

The LINQ query does this by using anested queryin theselectclause. The outer query iterates over the authors in the database. The inner query takes a specific author and re- trieves all titles that the author wrote. Theselectclause (lines 62–66) creates an anony- mous type with two properties:

• The propertyName(line 62) combines each author’s name, separating the first and last names by a space.

• The propertyTitles(line 63) receives the result of the nested query, which re- turns the title of each book written by the currentauthor.

In this case, we’re providing names for each property in the new anonymous type. When you create an anonymous type, you can specify the name for each property by using the formatname=value.

52 outputTextBox.AppendText(

53 String.Format( "\r\n\t{0,-10} {1,-10} {2}",

54 element.FirstName, element.LastName, element.Title1 ) );

55 } // end foreach 56

57 // get authors and titles of each book 58 // they co-authored; group by author 59 var titlesByAuthor =

60 61 62 63 64 65 66 67

68 outputTextBox.AppendText( "\r\n\r\nTitles grouped by author:" );

69

Fig. 22.27 | Getting a list of titles grouped by authors. (Part 1 of 2.)

Fig. 22.26 | Getting a list of authors and the titles of the books they’ve authored. (Part 2 of 2.)

from author in dbcontext.Authors

orderby author.LastName, author.FirstName

select new { Name = author.FirstName + " " + author.LastName, Titles =

from book in author.Titles orderby book.Title1

select book.Title1 };

Một phần của tài liệu Visual C 2012 How to Program _ www.bit.ly/taiho123 (Trang 915 - 920)

Tải bản đầy đủ (PDF)

(1.020 trang)