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

Beginning C# 2005 Databases PHẦN 3 ppsx

53 344 0

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

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 53
Dung lượng 663,7 KB

Nội dung

Figure 3-9: Choosing a query command type On this page you select the type of command that the query should execute. You can choose: ❑ Use SQL Statements: Enables you to create any SQL query you might like to as long as it returns either no result or a single result. You can also provide a parameterized query by which you can pass values to be used by the query (such as the ID of a row to delete in a delete query). ❑ Create New Stored Procedure: Similar to the preceding option, but the SQL you enter is used to create a stored procedure that is then accessed directly by the Query item. These also can be parameterized. ❑ Use Existing Stored Procedure: Creates a command that calls an existing stored procedure in the database, parameterized or not. Care should be taken here to use a stored procedure that returns no results or a single value; otherwise you cannot predict what you’ll receive as a return value. For the first two options, the next stage is to choose the type of SQL statement you are creating, as shown in Figure 3-10. As you can see, the only option unavailable is Select Which Returns Rows. You can, however, create any other type of SQL statement. The next step for a SQL command or stored procedure based on a SQL command is to enter the text of the command itself. You can either do that manually or use the SQL command builder, which enables you to design queries graphically. If you want to parameterize your queries, you can supply variable names in the form: @<Variable Name> 80 Chapter 3 44063c03.qxd:WroxBeg 9/15/06 12:42 PM Page 80 Figure 3-10: Choosing a query type For example, you could make a query as follows: SELECT StringColumn FROM MyTable WHERE MyTableId = @MyTableId This would return the value for a single column in a single row, where the row is identified by an ID value specified as a parameter called @MyTableId. If you are using an existing stored procedure, you are presented with a drop-down selector from which to choose a stored procedure to use. Then you will see the parameters that will be generated and the value that will be returned. Using the commands you generate is something that you will typically do from C# code that you write, although it is equally possible to bind the results of queries to control properties. TableAdapter The last object to consider is perhaps the one that you will use most often. Adding a TableAdapter actually results in the addition of several things. First, of course, you add a TableAdapter to which sev- eral Query objects will be added. In addition, you are adding a DataTable to contain the results of the select query that is added to the TableAdapter. The DataTable is also used when adding to or modify- ing database data. All of this, however, is achieved in a single step. Adding a TableAdapter can be done using the Toolbox window or by right-clicking in the DataSet Designer and selecting Add ➪ TableAdapter. In either case, you are presented with the TableAdapter Configuration Wizard. On the first page of this wizard, as with other wizards you have seen, you select or create a data connection to use. The next step is to choose a command type to use, as shown in Figure 3-11. 81 Viewing Data 44063c03.qxd:WroxBeg 9/15/06 12:42 PM Page 81 Figure 3-11: Choosing a command type The options here are as follows: ❑ Use SQL Statements: Enables you to create any SQL query you might like to as long as it returns table data. You can also provide a parameterized query with which you can pass values to be used by the query (such as the value of a column to use to filter the results returned). If you don’t use a join to select data from more than one table, the wizard can generate commands to insert, update, and delete data. ❑ Create New Stored Procedures: Similar to the preceding option, but the SQL you enter is used to create a stored procedure that is accessed directly by the TableAdapter item. If you don’t use a join to select data from more than one table, the wizard can generate stored procedures to insert, update, and delete data. ❑ Use Existing Stored Procedures: Creates a command that uses stored procedures to select, delete, modify, and add data. Assuming that you take the simplest option, and create a SQL select statement that selects tabular data from a single table, the next step is to create the SQL command. Again, you can use the graphical query builder to help you here, or you can just type the SQL statement in yourself. You can also choose from a selection of advanced options, shown in Figure 3-12. These options include whether to automatically generate insert, update, and delete statements; whether to generate these statements in such a way as to take concurrency (which is discussed shortly) into account; and whether the select statement is used to refresh data automatically when changes are sub- mitted to the underlying database. The latter options are available only if the first option is selected. Next, you have a few more options to choose from in the generation of the TableAdapter, as shown in Figure 3-13. 82 Chapter 3 44063c03.qxd:WroxBeg 9/15/06 12:42 PM Page 82 Figure 3-12: Choosing a command type Figure 3-13: Choosing a command type The options here are as follows: ❑ Fill A DataTable: Enables you to generate a method to fill a DataTable with results — which you usually want to do. In most circumstances the default name of the method, Fill(), is all you need. ❑ Return A DataTable: Generates a utility method that you can use to obtain a DataTable object from the TableAdapter directly, which can be useful in some circumstances as a shortcut. It certainly doesn’t hurt to leave this functionality in. You can rename the default value of GetData() if you really want to. ❑ Create Methods To Send Updates Directly To The Database (GenerateDBDirectMethods): Generates a set of methods that enable you to access the underlying database directly, rather than making changes to a data table and then submitting your changes in one go. This can be useful from your custom C# code. Again, it certainly doesn’t hurt to include these methods, unless you have a real reason not to. 83 Viewing Data 44063c03.qxd:WroxBeg 9/15/06 12:42 PM Page 83 The next step generates the TableAdapter and related/embedded items. Similarly, if you have chosen to use stored procedures, this completes your configuration. After the wizard has finished its operation, a new object appears in the DataSet Designer window, similar to that shown in Figure 3-14. Figure 3-14: The TableAdapter Configuration Wizard result The DataTable and TableAdapter items (Story and StoryTableAdapter in Figure 3-14) are linked together. After you have created a DataTable and TableAdapter combination this way, there is further configu- ration that you can perform. For example, you can add additional queries to the TableAdapter (includ- ing scalar value queries as per the previously mentioned Query item). You can also see the queries that have been generated previously by using the Properties window. For example, in the TableAdapter shown in Figure 3-14, four queries are generated. In the Properties window, you can see these by looking at the SelectCommand, InsertCommand, UpdateCommand, and DeleteCommand properties (expand them and look at the CommandText subproperty). The queries generated here are as follows: SELECT StoryId, EndingId, ClassificationId, SourceId, Name, Summary FROM dbo.Story INSERT INTO [dbo].[Story] ([StoryId], [EndingId], [ClassificationId], [SourceId], [Name], [Summary]) VALUES (@StoryId, @EndingId, @ClassificationId, @SourceId, @Name, @Summary); SELECT StoryId, EndingId, ClassificationId, SourceId, Name, Summary FROM Story WHERE (StoryId = @StoryId) UPDATE [Story] SET [StoryId] = @StoryId, [EndingId] = @EndingId, [ClassificationId] = @ClassificationId, [SourceId] = @SourceId, [Name] = @Name, [Summary] = @Summary WHERE (([StoryId] = @Original_StoryId) AND ([EndingId] = @Original_EndingId) AND ([ClassificationId] = @Original_ClassificationId) AND ([SourceId] = @Original_SourceId) AND ([Name] = @Original_Name)); SELECT StoryId, EndingId, ClassificationId, SourceId, Name, Summary FROM Story WHERE (StoryId = @StoryId) DELETE FROM [Story] WHERE (([StoryId] = @Original_StoryId) AND ([EndingId] = @Original_EndingId) AND ([ClassificationId] = @Original_ClassificationId) AND ([SourceId] = @Original_SourceId) AND ([Name] = @Original_Name)) Some of the automatically generated commands look a little odd. The reasons for this are as follows: ❑ The SELECT command is exactly what you’d expect — the list of columns is selected from the table. 84 Chapter 3 44063c03.qxd:WroxBeg 9/15/06 12:42 PM Page 84 ❑ The INSERT statement is also as expected, except that it includes a SELECT statement. This is a result of choosing the Refresh The Data Table option shown earlier; after adding a record, the record is loaded into the data table, using the primary key value StoryId to identify the new row. If you use an identity column for the primary key, the primary key won’t be available in this way because it is automatically generated by the database. In this case, the generated SQL code will use SCOPE_IDENTITY(), a SQL Server function that obtains the primary key value for the last row modified. In this example, the select query is used immediately after the insert query, so the function would return the primary key value for the row just added. ❑ The UPDATE statement includes a lot more code than you’d expect, particularly in its WHERE clause (it also has a SELECT statement, but it is just like the one detailed earlier). Because the Use Optimistic Concurrency option was selected, this statement checks the value of every col- umn value against the original row values rather than simply identifying the row to modify by its ID. This means that the row is modified only if all its values are as they were when the row was obtained from the database. If the row has changed, perhaps because of an external modifi- cation, the row won’t be modified, and an exception will be thrown. This is a simple technique to ensure that concurrency doesn’t become a problem. However, it is often overkill, especially in applications where the database data isn’t used by multiple users. Unselecting this option results in far simpler SQL code: UPDATE [Story] SET [StoryId] = @StoryId, [EndingId] = @EndingId, [ClassificationId] = @ClassificationId, [SourceId] = @SourceId, [Name] = @Name, [Summary] = @Summary WHERE (([StoryId] = @Original_StoryId)); SELECT StoryId, EndingId, ClassificationId, SourceId, Name, Summary FROM Story WHERE (StoryId = @StoryId) ❑ Similarly, the DELETE statement includes concurrency-checking code. Unselecting this option results in the following simple code: DELETE FROM [Story] WHERE (([StoryId] = @Original_StoryId)) Having the extra concurrency-checking code for update and delete commands isn’t that serious a prob- lem if you don’t need it, although performance may be slightly affected. Perhaps the biggest implication here is that if you include the concurrency check, you have to add additional code to detect concurrency violations and act on them, which can complicate your applications. Of course, you can simply ignore errors, but that may adversely affect the end user experience. You’ll learn a lot more about this in Chapter 9. A final point when adding TableAdapter items this way is that relationships are detected automatically by the wizard. If you add data from one table, and subsequently add data from a second, related table in another TableAdapter, a Relation item is generated for you, matching the relationship defined in the underlying database. Adding Objects from the Database Explorer Window You can add data structures to the DataSet Designer directly from the Database Explorer window. You can, for example, drag a table from the Database Explorer to the designer. What happens next is a thing of beauty — everything that you’d otherwise have to do with a wizard happens automatically. The end result is the same as if you’d added a TableAdapter item and configured it using the wizard, but all the options are chosen for you. 85 Viewing Data 44063c03.qxd:WroxBeg 9/15/06 12:42 PM Page 85 If you want to add a subset of the rows in a table, you can — just select the rows you want to add from a table and drag them onto the DataSet Designer as a single unit. You can add stored procedures in the same way. However, this ease of use comes at a price — flexibility. If you want to perform more advanced opera- tions, you have to use other methods, or customize the resultant objects after you have added them. In the next Try It Out, you use the DataSet Designer to create a data source manually. Note that some of the instructions in this Try It Out are deliberately kept short — but don’t worry if you have to refer to the preceding text and explanations to help you along the way. Try It Out Manually Configuring a Data Source 1. In Windows Explorer, copy the contents of the C:\BegVC#Databases\Chapter03\Ex0301 - Automatic Configuration directory to a new directory called C:\BegVC#Databases\ Chapter03\Ex0302 - Manual Configuration . 2. Open the Ex0301 - Automatic Configuration.sln solution file from the version of the project stored in the new directory (that is, not the version of the solution file saved in the previ- ous Try It Out, but the new version of the file that you just created by copying the old one). Opening this file opens Visual C# Express 2005. 3. In the Solution Explorer window, rename both the solution and project to Ex0302 - Manual Configuration . This also renames the solution and project files. 4. Save all files. 5. Right-click on the project in Solution Explorer and select Add ➪ New Item. 6. Add a new DataSet item called FolkDBDataSet2.xsd. 7. Right-click in the DataSet Designer for the new data set and select Add ➪ TableAdapter. 8. Use the existing connection, the Use SQL Statements command type, and the following select query: SELECT * FROM Story 9. Leave the rest of the options available in the wizard with their default options and click Finish. 10. Drag the Classification and Source tables from the Database Explorer window onto the Data - Set Designer (note that you have to expand the database and database tables to see these tables). 11. Right-click the DataSet Designer and select Add ➪ Query. 12. Use the existing connection and default options, and add the following scalar query with the name StoryCountQuery: SELECT COUNT(*) FROM Story 13. Right-click QueriesTableAdapter (the table adapter you just added) and click Add Query. 14. Add the following query with default options and the name CharactersByStoryIdCount: SELECT COUNT(*) FROM CharacterStory WHERE StoryId = @StoryId 15. Save all files and close Visual C# 2005. 86 Chapter 3 44063c03.qxd:WroxBeg 9/15/06 12:42 PM Page 86 How It Works The first thing you did in this Try It Out was to copy the project created in the previous Try It Out to a new project with a different name. The steps required to do this (steps 1–4) are ones that you will carry out several times in this and subsequent chapters (copy the files, open the copied project, rename the solution and project, and save the files). In other Try It Outs, this series of steps will be abbreviated to “Copy project X as project Y.” When you see that, you might want to refer back to these steps to make sure you do things correctly. Once you had a new project to play with, you added a second data source, but this time you did things manually. If all has gone as planned, you should have generated a data set just like the one shown in Figure 3-15. Figure 3-15: A manually added data set As with the previous Try It Out, you make use of this data set later in the chapter. Advanced Data Source Configuration This section introduces you to some of the more advanced techniques you can use to configure data sources, namely: ❑ Filtering data ❑ Modifying data set code Although these topics aren’t covered in depth here, you explore them in more detail later in the book. 87 Viewing Data 44063c03.qxd:WroxBeg 9/15/06 12:42 PM Page 87 Filtering Data When you bind controls to a data source it is perfectly possible, indeed often desirable, to filter the data in the data set and display a subset of the records contained therein. There is, however, another option for filtering: retrieving only the filtered rows from the database. The advantage is that less data is stored in the data table in the data set; the disadvantage is that the database must be queried every time the fil- ter changes. For rapidly changing data this needn’t be a problem because the data is refreshed from the source data when the filter changes, so updates to the database are reflected in the data retrieved. To do this in practice you must add additional queries to a TableAdapter item. This procedure works in much the same way as adding queries to the TableAdapter used to group Query items, which you saw earlier. The difference, as with the base query for TableAdapters linked to DataTable items, is that a query used to filter row data returns a set of rows, not a single value (or no value). To add a query to a TableAdapter, right-click it and select Add Query. The query addition works in the same way as adding the base query. You start by selecting the command type (SQL Query, SQL Query To Be Copied To A Stored Procedure, or Existing Stored Procedure). Next, for SQL queries, you choose the type of query, which should be a select query that returns rows for a filter query (you cannot add a query of this type to a stand-alone query object, because you can have only queries that return rows for table adapters with an associated data table). When entering the query, use parameters. For example: SELECT StoryId, EndingId, ClassificationId, SourceId, Name, Summary FROM Story WHERE EndingId = @EndingId Then name the methods used to execute the query; it is typical to use a name that reflects the filter. For the preceding query you might use FillByEndingId() and GetDataByEndingId(), as shown in Figure 3-16. Figure 3-16: Adding a filter query 88 Chapter 3 44063c03.qxd:WroxBeg 9/15/06 12:42 PM Page 88 You can use this query from data-bound controls (or custom code) to retrieve filtered data. There is no limit to the number or complexity of additional queries that you can add to a TableAdapter in this way. However, you must make the queries return the same set of columns as the base query; otherwise, the schema of the DataTable will fail to load the data successfully and you will receive errors. It is worth noting that when data-binding controls, you can filter data directly from the wizards used to configure data binding in Windows Forms. Still, there will be times when you want to do this manually, using the DataSet Designer. Modifying Data Set Code By now you’ve probably noticed that generating a typed data set for a data source results in several types of files being added to your project. In particular, a partial class definition is generated for the data set, which defines the typed DataSet class. That class inherits from System.Data.DataSet and includes the following: ❑ Nested class definitions for tables, rows, relationships, row-changing events, and row-changing event handlers ❑ Strongly typed methods, properties, and events for accessing rows, columns, and constraints, using the nested type definitions and reacting to data changes The nested class definitions also contain a variety of methods and properties to ease navigation between rows, retrieving specific rows by their primary key value, and accessing related data. For example, the class definition for a row in a table that is a parent row for child rows in a related table includes a method to retrieve all child rows in one go. The naming of all these files, classes, and methods uses the database schema information. A data set called MyDataSet containing a TableAdapter that retrieves data for a table called MyTable is defined in a code file called MyDataSet.Designer.cs. That file will contain a DataSet-derived class called MyDataSet, defined in the default project namespace. It will also contain a class derived from System.ComponentModel.Component called MyTableTableAdapter, defined in the namespace <default project namespace>.MyDataSetTableAdapters. This table adapter class contains meth- ods for populating data table classes and making changes to the database, as well as methods correspon- ding to each query contained in the table adapter. The exact code generated reflects the structure of the typed data set you define, including many attrib- utes relating to XML serialization and such, as well as the types previously mentioned. The best way to get a feel for this is to play around and see what code is generated. You’ll see the ADO.NET classes being used throughout the generated code, and while much of the code won’t make a lot of sense at this point, you’ll get the idea. Now, the reason for bringing all this up is that the code generated is only a starting point for typed data set code. Because the code generated is for partial class definitions, you can supply your own code. You shouldn’t modify the code in the <data set>.Designer.cs file, but you can supply your own code in a file called <data set>.cs. That file isn’t created by default, but as soon as you want to edit it, it’s gener- ated for you. This happens if, for example, you double-click in the DataSet Designer window, or if you right-click on the data set in Solution Explorer and select View Code. 89 Viewing Data 44063c03.qxd:WroxBeg 9/15/06 12:42 PM Page 89 [...]... BindingNavigator control is via an example, so follow these steps: 1 2 3 102 Copy the project C:\BegVC #Databases\ Chapter 03\ Ex 030 4 - Parent Binding to a new project, C:\BegVC #Databases\ Chapter 03\ Ex 030 5 - BindingNavigator Open Form1 in design view Add a BindingNavigator control to the form 44063c 03. qxd:WroxBeg 9/15/06 12:42 PM Page 1 03 Viewing Data 4 In the BindingNavigator Tasks window, select the following:... want to apply from your data-bound controls 107 44063c 03. qxd:WroxBeg 9/15/06 12:42 PM Page 108 Chapter 3 Again, this is much simpler than it sounds and best illustrated with an example Try It Out Filtering Data 1 Copy the project C:\BegVC #Databases\ Chapter 03\ Ex 030 6 - Detail Binding to a new project, C:\BegVC #Databases\ Chapter 03\ Ex 030 7 - Filtering 2 3 Open Form1 in design view 4 5 On the Tasks window... related data, something that was only touched on in this chapter 110 44063c 03. qxd:WroxBeg 9/15/06 12:42 PM Page 111 Viewing Data Exercises 1 2 What is a connection string? What sort of information does it contain? 3 Copy the project C:\BegVC #Databases\ Chapter 03\ Ex 030 4 - Parent Binding to a new project, C:\BegVC #Databases\ Chapter 03\ Q 030 3 - Extended Binding Modify the project by replacing the SourceId column... 2 3 4 5 100 Copy the project C:\BegVC #Databases\ Chapter 03\ Ex 030 3 - Large Text to a new project, C:\BegVC #Databases\ Chapter 03\ Ex 030 4 - Parent Binding Open Form1 in design view In the DataGridView Tasks window for the dataGridView1 control, click Edit Columns Change the type of the ClassificationId column to DataGridViewComboBoxColumn Set the following properties of the ClassificationId column: 44063c 03. qxd:WroxBeg... clicked, displays text in a pop-up dialog box Here are the steps to accomplish that: 1 Copy the project C:\BegVC #Databases\ Chapter 03\ Ex 030 2 - Manual Configuration to a new project, C:\BegVC #Databases\ Chapter 03\ Ex 030 3 - Large Text, using the procedure described in the previous Try It Out 2 3 4 5 Open Form1 in design view 6 7 Resize Form1 so that all the columns fit in the form without having to scroll... FolkDBDataSet2.StoryRow).Summary; MessageBox.Show(summaryText, “Story Summary”, MessageBoxButtons.OK); } } 12 13 98 Run the application and click Show for a row The result should look like Figure 3- 23 Close the application and Visual C# Express 44063c 03. qxd:WroxBeg 9/15/06 12:42 PM Page 99 Viewing Data Figure 3- 23: Large text view How It Works In this example, you did two things First, you bound a control to a... exercise, you see for yourself how straightforward it is to bind to a detail view Just follow these steps: 1 Copy the project C:\BegVC #Databases\ Chapter 03\ Ex 030 2 - Manual Binding to a new project, C:\BegVC #Databases\ Chapter 03\ Ex 030 6 - Detail Binding 2 3 4 5 Open Form1 in design view In the Data Sources window, expand FolktaleDBDataSet and Character Set the options for the Character table so that it can... onto the form Run the application The result is shown in Figure 3- 30 Position and resize the fields to obtain an aesthetically pleasing layout The TextBox control for the Notes column needs to have a Multiline property of True Close the application and Visual C# Express 44063c 03. qxd:WroxBeg 9/15/06 12:42 PM Page 107 Viewing Data Figure 3- 30: Parent binding display How It Works In this example you created... Figure 3- 31), and then click OK: SELECT FROM WHERE CharacterId, SpeciesId, MotherId, FatherId, Name, Gender, Notes, Email, Occupation, Age Character Gender = @Gender Figure 3- 31: Adding a filter query 6 7 108 Run the application Type a gender (Male or Female) into the Gender text box at the top of the form and click FillByGender to filter the results that you can view, as shown in Figure 3- 32 Close... shown in Figure 3- 28) is shown in Figure 3- 29 Figure 3- 29: Adding a detail view As with automatically generated DataGridView controls, there is more configuration to be done, such as resizing and positioning the controls that are generated for you Even at this point, however, you have a working application, in which you can navigate through database data and see what’s there 105 44063c 03. qxd:WroxBeg . the C:BegVC #Databases Chapter 03 Ex 030 1 - Automatic Configuration directory to a new directory called C:BegVC #Databases Chapter 03 Ex 030 2 - Manual Configuration . 2. Open the Ex 030 1 - Automatic. accomplish that: 1. Copy the project C:BegVC #Databases Chapter 03 Ex 030 2 - Manual Configuration to a new project, C:BegVC #Databases Chapter 03 Ex 030 3 - Large Text, using the procedure described. The result should look like Figure 3- 23. 13. Close the application and Visual C# Express. 98 Chapter 3 44063c 03. qxd:WroxBeg 9/15/06 12:42 PM Page 98 Figure 3- 23: Large text view How It Works In

Ngày đăng: 08/08/2014, 18:21

TỪ KHÓA LIÊN QUAN