Dynamically Binding Query Results

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

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

22.6 Dynamically Binding Query Results

enables you to order results by an additional column. This is applied to theAuthorobjects that have already been ordered by last name.

Finally, line 30 calls theLoadextension method(defined in classDBExtensionsfrom the namespaceSystem.Data.Entity). This method executes the LINQ to Entities query and loads the results into memory. This data is tracked by theBookEntities DbContext

in local memory so that any changes made to the data can eventually be saved into the database. Lines 27–30 are equivalent to using the following statement:

Line 33 sets theauthorBindingSource’sDataSourcepropertyto theLocalproperty of thedbcontext.Authorsobject. In this case, theLocalproperty is anObservableCol- lection<Author>that represents the query results that were loaded into memory by lines 27–30. When aBindingSource’sDataSourceproperty is assigned anObservableCollec- tion<T>(namespaceSystem.Collections.ObjectModel), the GUI that’s bound to the

BindingSourceis notified of any changes to the data so the GUI can be updated accord- ingly. In addition, changes made by the user to the data in the GUI will be tracked so the

DbContextcan eventually save those changes to the database.

authorBindingNavigatorSaveItem_ClickEvent Handler: Saving Modifications to the Database

If the user modifies the data in theDataGridView, we’d also like to save the modifications in the database. By default, theBindingNavigator’sSave DataButton( ) is disabled.

To enable it, right click thisButton’s icon in theBindingNavigatorand selectEnabled. Then, double click the icon to create itsClickevent handler (lines 38–54).

Saving the data entered in theDataGridViewback to the database is a three-step process.

First, all controls on the form are validated (line 41) by calling theDisplayTableForm’s inheritedValidatemethod—if any control has an event handler for theValidatingevent, it executes. You typically handle this event to determine whether a control’s contents are valid. Next, line 42 callsEndEditon theauthorBindingSource, which forces it to save any pending changes into theBooksEntities model in memory. Finally, line 47 calls Save-

Changeson theBooksEntitiesobject (dbcontext) to store any changes into the database.

We placed this call in atrystatement, because theAuthorstable does not allow empty values for the first name and last name—these rules were configured when we originally created the database. WhenSaveChangesis called, any changes stored into theAuthorstable must sat- isfy the table’s rules. If any of the changes do not, aDBEntityValidationExceptionoccurs.

22.6 Dynamically Binding Query Results

Now that you’ve seen how to display an entire database table in aDataGridView, we show how to perform several different queries and display the results in aDataGridView. This app only reads data from the entity data model, so we disabled the buttons in theBind-

ingNavigatorthat enable the user to add and delete records. Later, we’ll explain why we do not support modifying the database in this example.

TheDisplay Query Resultsapp (Fig. 22.21) allows the user to select a query from the

ComboBoxat the bottom of the window, then displays the results of the query.

(from author in dbcontext.Authors

orderby author.LastName, author.FirstName select author).Load();

22.6.1 Creating theDisplay Query ResultsGUI

Perform the following steps to build theDisplay Query Resultsapp’s GUI.

Step 1: Creating the Project

Perform the steps in Section 22.5.2 to create a newWindows Forms Applicationproject namedDisplayQueryResultin the same solution as theDisplayTableapp. Rename the

Form1.cssource file toTitleQueries.cs. Set theForm’sTextproperty toDisplay Query Results. Be sure to set theDisplayQueryResultproject as the startup project.

Step 2: Creating aDataGridViewto Display theTitlesTable

FollowSteps 1and2in Section 22.5.3 to create the data source and theDataGridView. For this example, select theTitleclass (rather thanAuthor) as the data source, and drag theTitlenode from theData Sourceswindow onto the form. Remove theAuthorscolumn from theDataGridViewas it will not be used in this example.

Fig. 22.21 | Sample execution of theDisplay Query Resultsapp.

a) Results of the

“All titles” query, which shows the contents of the Titlestable ordered by the book titles

b) Results of the

“Titles with 2014 copyright” query

c) Results of the

“Titles ending with ’How to Program’” query

22.6 Dynamically Binding Query Results 871

Step 3: Adding aComboBoxto theForm

InDesignview, add aComboBoxnamedqueriesComboBoxbelow theDataGridViewon the

Form. Users will select which query to execute from this control. Set theComboBox’sDock property toBottomand theDataGridView’sDockproperty toFill.

Next, you’ll add the names of the queries to theComboBox. Open theComboBox’sString

Collection Editorby right clicking theComboBoxand selectingEdit Items…. You can also access theString Collection Editorfrom theComboBox’ssmart tag menu. Asmart tag menu provides you with quick access to common properties you might set for a control (such as theMultilineproperty of aTextBox), so you can set these properties directly inDesign view, rather than in thePropertieswindow. You can open a control’ssmart tag menuby clicking the small arrowhead ( ) that appears in the control’s upper-right corner inDesign view when the control is selected. In theString Collection Editor, add the following three items toqueriesComboBox—one for each of the queries we’ll create:

1. All titles

2. Titles with 2014 copyright

3. Titles ending with "How to Program"

22.6.2 Coding theDisplay Query ResultsApp Next you’ll create the code for this app (Fig. 22.22).

Customizing theForm’sLoadEvent Handler

Create theTitleQueries_Loadevent handler (lines 22–29) by double clicking the title bar inDesignview. When theFormloads, it should display the complete list of books from the

Titlestable, sorted by title. Line 24 calls theLoadextension method on theBookEnti-

ties DbContext’sTitlesproperty to load theTitlestable’s contents into memory. Rath- er than defining the same LINQ query as in lines 40–41, we can programmatically cause thequeriesComboBox_SelectedIndexChangedevent handler to execute simply by setting thequeriesComboBox’sSelectedIndexto0(line 28).

1 // Fig. 22.22: TitleQueries.cs

2 // Displaying the result of a user-selected query in a DataGridView.

3 using System;

4 using System.Data.Entity;

5 using System.Linq;

6 using System.Windows.Forms;

7

8 namespace DisplayQueryResult 9 {

10 public partial class TitleQueries : Form

11 {

12 public TitleQueries()

13 {

14 InitializeComponent();

15 } // end constructor 16

Fig. 22.22 | Displaying the result of a user-selected query in aDataGridView. (Part 1 of 2.)

17 // Entity Framework DbContext

18 private BooksExamples.BooksEntities dbcontext = 19 new BooksExamples.BooksEntities();

20

21 // load data from database into DataGridView

22 private void TitleQueries_Load( object sender, EventArgs e )

23 {

24 25

26 // set the ComboBox to show the default query that 27 // selects all books from the Titles table

28

29 } // end method TitleQueries_Load 30

31 // loads data into titleBindingSource based on user-selected query 32 private void queriesComboBox_SelectedIndexChanged(

33 object sender, EventArgs e )

34 {

35 // set the data displayed according to what is selected 36 switch ( queriesComboBox.SelectedIndex )

37 {

38 case 0: // all titles

39 // use LINQ to order the books by title 40

41

42 break;

43 case 1: // titles with 2014 copyright 44 // use LINQ to get titles with 2014 45 // copyright and sort them by title 46

47 48 49

50 break;

51 case 2: // titles ending with "How to Program"

52 // use LINQ to get titles ending with 53 // "How to Program" and sort them by title 54

55 56 57 58

59 break;

60 } // end switch

61 62

63 } // end method queriesComboBox_SelectedIndexChanged 64 } // end class TitleQueries

65 } // end namespace DisplayQueryResult

Fig. 22.22 | Displaying the result of a user-selected query in aDataGridView. (Part 2 of 2.)

dbcontext.Titles.Load(); // load Titles table into memory

queriesComboBox.SelectedIndex = 0;

titleBindingSource.DataSource =

dbcontext.Titles.Local.OrderBy( book => book.Title1 );

titleBindingSource.DataSource = dbcontext.Titles.Local

.Where( book => book.Copyright == "2014" ) .OrderBy( book => book.Title1 );

titleBindingSource.DataSource = dbcontext.Titles.Local

.Where( book =>

book.Title1.EndsWith( "How to Program" ) ) .OrderBy( book => book.Title1 );

titleBindingSource.MoveFirst(); // move to first entry

22.6 Dynamically Binding Query Results 873

queriesComboBox_SelectedIndexChangedEvent Handler

Next you must write code that executes the appropriate query each time the user chooses a different item fromqueriesComboBox. Double clickqueriesComboBoxinDesignview to generate aqueriesComboBox_SelectedIndexChangedevent handler (lines 32–63) in the

TitleQueries.csfile. In the event handler, add aswitchstatement (lines 36–60). Each

casein theswitchwill change thetitleBindingSource’sDataSourceproperty to the re- sults of a query that returns the correct set of data. The data bindings created by the IDE automaticallyupdate thetitleDataGridVieweach time we change itsDataSource. The

MoveFirstmethodof theBindingSource(line 62) moves to the first row of the result each time a query executes. The results of the queries in lines 40–41, 46–49 and 54–58 are shown in Fig. 22.21(a), (b) and (c), respectively. Because we do not modify the data in this app, each of the queries is performed on the in-memory representation of theTitlestable, which is accessible throughdbcontext.Titles.Local.

Ordering the Books By Title

Lines 40–41 invoke theOrderByextension method ondbcontext.Titles.Localto order theTitleobjects by theirTitle1property values. As we mentioned previously, the IDE renamed theTitlecolumn of the database’sTitlestable asTitle1in the generatedTi-

tleentity data model class to avoid a naming conflict with the class’s name. Recall that

Localreturns anObservableCollection<T>containing the row objects of the specified table—in this case,Localreturns anObservableCollection<Title>. When you invoke

OrderByon anObservableCollection<T>, the method returns anIEnumerable<T>. We assign that object to thetitleBindingSource’sDataSourceproperty. When theData-

Sourceproperty changes, theDataGridViewiterates through the contents of theIEnumer-

able<T>and displays the data.

Selecting Books with 2014 Copyright

Lines 46–49 filter the titles displayed by using theWhereextension methodwith the lamb- da expression

as an argument. This lambda expression takes oneTitleobject (namedbook) as its pa- rameter and uses it to check whether the givenTitle’sCopyrightproperty (astringin the database) is equal to2014. A lambda expression that’s used with theWhereextension method must return aboolvalue. OnlyTitleobjects for which this lambda expression returnstruewill be selected. We useOrderByto order the results by theTitle1property so the books are displayed in ascending order by title. The type of the lambda’sbookpa- rameter isinferredfromdbcontext.Titles.Local, which containsTitleobjects. As soon as thetitleBindingSource’sDataSourceproperty changes, theDataGridViewis updated with the query results.

Selecting Books with Titles That End in “How to Program”

Lines 54–58 filter the titles displayed by using theWhereextension method with the lamb- da expression

book => book.Copyright == "2014"

book => book.Title1.EndsWith( "How to Program" )

as an argument. This lambda expression takes oneTitleobject (namedbook) as its pa- rameter and uses it to check whether the givenTitle’sTitle1property value ends with

"How to Program". The expressionbooks.Title1returns thestringstored in that prop- erty, then we use the string class’sEndsWithmethod to perform the test. We order the re- sults by theTitle1property so the books are displayed in ascending order by title.

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

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

(1.020 trang)