Tài liệu Use Visual Studio .NET Tools to Speed Up Writing ADO.NET doc

15 371 0
Tài liệu Use Visual Studio .NET Tools to Speed Up Writing ADO.NET doc

Đ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

9.3 Use Visual Studio .NET Tools to Speed Up Writing ADO.NET Code The code you've written up to this point doesn't do that much. It doesn't even access the database. The next task is to write code that populates the class with data from the database, and the first step in doing this is setting up database access objects. Technique In Chapter 3, you learned how to fill a dataset to store data in a disconnected fashion. In this chapter, you will use a strongly typed dataset-that is, a dataset with data rows that match the name and datatypes of the columns. You will learn how to use the DataAdapter Configuration Wizard to autogenerate code that initializes Command and DataAdapter objects for use with a specific table. Steps 1. Right-click on your project and select Add New Item from the Add menu. Choose DataSet and name it dsCustomers.xsd. 2. Visual Studio .NET opens dsCustomers.xsd in Design mode. Expand the Server explorer and drill down to Data Connections, Northwind, Tables. Drag the Customers table onto the Design view. 3. Visual Studio might process for a few seconds, but afterward, you'll have a strongly typed dataset. The result? Instead of writing dataset code like this: strCustomerID = CType(ds.Tables("Customers").Rows(0).Item("CustomerID"), String) you'll have code that looks like this: strCustomerID = ds2.Customers(0).CustomerID A strongly typed dataset is a combination of two documents. One is a .vb file with the same name as the dataset. Visual Studio .NET will not show you the contents of this file (unless you step into it while debugging), and the contents don't appear in the Solution Explorer. The other file is an .xsd file, or a XML Schema Definition (XSD), which defines a data structure. The .vb file reads the XSD to properly instantiate a strongly typed dataset. You should always take a look at any code that is generated automatically by a tool because the tool might generate code that doesn't do precisely what you want it to do. If you have never seen an XSD, this is also a good time to learn something new. Listing 9.18 shows the XSD for the dsCustomers dataset. You can view the XSD you created by opening dsCustomers.xsd from the Solution Explorer and then clicking the XML button at the bottom of left corner of the screen. Listing 9.18 dsCustomers.xsd: The Customers XSD <?xml version="1.0" encoding="utf-8" ?> <xsd:schema id="dsCustomers" targetNamespace="http://tempuri.org/dsCustomers.xsd" elementFormDefault="qualified" xmlns="http://tempuri.org/dsCustomers.xsd" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> <xsd:element name="dsCustomers" msdata:IsDataSet="true"> <xsd:complexType> <xsd:choice maxOccurs="unbounded"> <xsd:element name="Customers"> <xsd:complexType> <xsd:sequence> <xsd:element name="CustomerID" type="xsd:string" /> <xsd:element name="CompanyName" type="xsd:string" /> <xsd:element name="ContactName" type="xsd:string" minOccurs="0" /> <xsd:element name="ContactTitle" type="xsd:string" minOccurs="0" /> <xsd:element name="Address" type="xsd:string" minOccurs="0" /> <xsd:element name="City" type="xsd:string" minOccurs="0" /> <xsd:element name="Region" type="xsd:string" minOccurs="0" /> <xsd:element name="PostalCode" type="xsd:string" minOccurs="0" /> <xsd:element name="Country" type="xsd:string" minOccurs="0" /> <xsd:element name="Phone" type="xsd:string" minOccurs="0" /> <xsd:element name="Fax" type="xsd:string" minOccurs="0" /> </xsd:sequence> </xsd:complexType> </xsd:element> </xsd:choice> </xsd:complexType> <xsd:unique name="dsCustomersKey1" msdata:PrimaryKey="true"> <xsd:selector xpath=".//Customers" /> <xsd:field xpath="CustomerID" /> </xsd:unique> </xsd:element> </xsd:schema> It is beyond the scope of this chapter and this book to fully explain an XSD. The subject requires an entire book of its own. But it's important to point out a few areas of this XSD. The element tags are really nothing more than the properties you have already declared. Each element has a name that corresponds to a column in the Customers table, as well as a type that loosely corresponds to the datatype of the column. The element tag also has a minOccurs attribute. This attribute actually defines whether a value is required for that element. The default for the minOccurs attribute is 1, which means that the element does not allow Null values. Also, take a close look at the lines at the end of the XSD that begin with <xsd:unique. This XML block refers back to the CustomerID element, and it declares that that element is the primary key of the dsCustomers XSD. A dataset is just one part of what you need. Without a data adapter, the dataset just sits there. You could create all the data adapter code yourself, but again, Visual Studio .NET can do a lot of the work for you. 4. Right-click on your project and select Add New Item from the Add menu. Choose Component Class and name it CCustomerData.vb. 5. Visual Studio opens CCustomerData.vb in Design mode. Expand the Toolbox on the left side of the screen. Choose the Data tab, and drag an OleDbConnection onto the Design view. 6. Click on OleDbConnection1 and rename it oleCnn. 7. Set the ConnectionString property. You should have an existing connection to the Northwind database. (You set this up in section 9.1.) If you don't have an existing connection, create a connection by selecting New Connection from the ConnectionString menu. 8. Drag an OleDbDataAdapter from the Data tab of the Toolbox. Doing so opens the DataAdapter Configuration Wizard. 9. First, in the Choose Your Data Connection page of the wizard, shown in Figure 9.2, select a connection for the data adapter, and then click Next. Figure 9.2. The Choose Your Data Connection page of the DataAdapter Configuration Wizard. 10. Now, you have the option of choosing the type of query to use with the data adapter. For the purposes of this example, use SQL statements. The other choices, shown in Figure 9.3, allow you to specify existing stored procedures, or have the wizard create new database stored procedures for you. Figure 9.3. The Choose a Query Type page of the DataAdapter Configuration Wizard. 11. The next page of the wizard, shown in Figure 9.4, asks for a SQL statement to retrieve data from the database. Choose Query Builder to create a new query. Figure 9.4. The Generate the SQL Statements page of the DataAdapter Configuration Wizard. 12. Using the Query Builder, shown in Figure 9.5, select the Customers table, and return all the columns in the table. Add a WHERE condition to select a single customer row based on the Customer ID as in Listing 9.19. Click Next and then Finish. Listing 9.19 CustomerData.vb: The SELECT Command Text to Use in the DataAdapter Configuration Wizard SELECT CustomerID, CompanyName, ContactName, ContactTitle, Address, City, Region, PostalCode, Country, Phone, Fax FROM Customers WHERE CustomerID = ? Figure 9.5. The Query Builder allows you to graphically build a SQL statement. 13. Again, Visual Studio picks some undescriptive and bland names for the data adapter and its Select, Update, Insert, and Delete commands. In this example, OleDbAdapter1 will be renamed to odaCustomers, and OleDb[Action]Command1 will be renamed to [Action]Customer. 14. Finally, right-click on odaCustomers and select Properties. In the Properties window, expand the TableMappings property, which will open a dialog box like that shown in Figure 9.6. This property tells Visual Studio .NET where to look for datatype and column information. The DataAdapter Configuration Wizard will have referenced the Customers table because it was not aware of the XSD you created earlier in this section. Check on the Use a Dataset to Suggest Table and Column Names check box, and select dsCustomers from the DataSet combo box. Make sure that the DataSet Table combo box references the Customers table of the dataset. Figure 9.6. The Table Mappings collection of the data adapter. Based on the query you entered, Visual Studio .NET will generate Update, Delete, and Insert SQL statements for the Customers table, as well as code that populates the parameter collections and other properties of Command objects based on those SQL statements. Most important, if you modify the SQL statements, Visual Studio .NET updates the Visual Basic code setting up their command objects. The SQL statements that Visual Studio .NET generates might be a bit more complex than you need. In Listing 9.20, the UPDATE command has a WHERE condition that references every column instead of just the primary key. Listing 9.20 CustomerData.vb: The Update Command Text from the Visual Studio .NET-Generated Data Adapter UPDATE Customers SET CustomerID = ?, CompanyName = ?, ContactName = ?, ContactTitle = ?, Address = ?, City = ?, Region = ?, PostalCode = ?, Country = ?, Phone = ?, Fax = ? WHERE (CustomerID = ?) AND (CompanyName = ?) AND (Address = ? OR ? IS NULL AND Address IS NULL) AND (City = ? OR ? IS NULL AND City IS NULL) AND (ContactName = ? OR ? IS NULL AND ContactName IS NULL) AND (ContactTitle = ? OR ? IS NULL AND ContactTitle IS NULL) AND (Country = ? OR ? IS NULL AND Country IS NULL) AND (Fax = ? OR ? IS NULL AND Fax IS NULL) AND (Phone = ? OR ? IS NULL AND Phone IS NULL) AND (PostalCode = ? OR ? IS NULL AND PostalCode IS NULL) AND (Region = ? OR ? IS NULL AND Region IS NULL) This SQL statement is guaranteed to make sure you update only the record you retrieved. If the record has changed in another session since the data was retrieved by the current session, that row won't be updated. This might be the behavior you need in some situations. Still, the whole point of a primary key is that it fully represents all the non-key values in the table (and, of course, none of the non-key values should rely on each other for definition), so perhaps that WHERE condition is overkill. You might also have noticed that the SET clause of the UPDATE statement that Visual Studio .NET generated updates the value of the CustomerID column. In the case of the Customers table, this SQL statement could not execute because DRI is enforcing the relationship with the Orders table. However, not all databases use DRI; if the CustomerID were changed in that scenario, the code would execute and orphan rows in other tables that contain the old CustomerID value. In that case, it would be best to modify the Visual Studio .NET-generated SQL statements to reflect the primary key and make the code more sensible. For example, the UPDATE statement from Listing 9.20 would read as shown in Listing 9.21. You can access the Insert, Update, and Delete SQL statements used by the data adapter by expanding the related command in the Properties window. Then look for the CommandText property and click on the Ellipsis button, as shown in Figure 9.7. Listing 9.21 CustomerData.vb: A Simpler Update Command Text from the Visual Studio .NET-Generated Data Adapter UPDATE Customers SET CompanyName = ?, ContactName = ?, ContactTitle = ?, Address = ?, City = ?, Region = ?, PostalCode = ?, Country = ?, Phone = ?, Fax = ? WHERE (CustomerID = ?) Figure 9.7. The Properties window allows you to access the CommandText property by expanding the data adapter's Update command. When you do modify those statements, you'll notice that a SELECT SQL statement follows the Insert and Update commands. In ADO 2.x, a cursor was maintained on the server using server resources or on the client with a connection to the server. This meant that an updateable recordset would receive notification of data changes, such as the value of an IDENTITY or other auto- incrementing column after inserting a new row or the values of updated data after an UPDATE trigger made additional changes. The open connection and cursor, however, consume substantial resources and can adversely affect server performance. ADO.NET's disconnected architecture is an attempt to resolve this resource problem. Still, refreshing the dataset with the most current data can be quite helpful in databases that have triggers or complex stored procedures, so this second SQL command will retrieve the updated [...]... make the OLE DB command we instantiated above the update command ' for the data adapter Me.odaCustomers.UpdateCommand = Me.updateCustomer ' set the connection for the update command Me.updateCustomer.Connection = Me.oleCnn ' set the command text of the update command to the SQL statements from ' Listing 9.16 Me.updateCustomer.CommandText = _ "UPDATE Customers SET CompanyName = ?, ContactName = ?, ContactTitle... will use to connect to the database In other words, Visual Studio NET has written more than 100 lines of code, or four pages of dull, repetitive code in a matter of minutes More important, Visual Studio NET will update this code automatically whenever changes are made to the data adapter's properties How It Works With the updates you have made to the Delete, Update, and Insert commands, as well as to. .. that Visual Studio NET also created an UPDATE statement that could have modified the primary key of the Customers table That's a problem in and of itself, but consider the potential issues with an UPDATE statement that tries to update an autoincrementing identity column Visual Studio NET will generate the same type of UPDATE statement and attempt to change the value of that column However, because the... when loading that XML than a regular dataset That's because a regular dataset has to shred the XML document twicefirst to infer the schema, and second to extract the data A strongly typed dataset, in contrast, already knows its schema, so it has to shred the document only once Visual Studio NET Auto-Generated SQL Some larger issues stem from the UPDATE SQL statement in Listing 9.19, which referenced... of an auto-incrementing identity column cannot be updated (DRI or no), the SQL statement fails to execute and an exception is thrown Any time that Visual Studio NET generates code for you, examine that code thoroughly to make sure it does precisely what you want You should also be wary when you ask ADO.NET to generate commands on-the-fly, for example, when using a CommandBuilder object ADO.NET creates... generates This discussion is not meant to denigrate or downplay Visual Studio NET's codegeneration capabilities On the contrary, Microsoft has provided some extraordinarily powerful tools As you saw in Listing 9.22 in this section, the code that Visual Studio NET creates is repetitive to write and tedious to maintain With just a little bit of direction from you, Visual Studio NET can save you hours of mundane... dataset, you have all the code you need to retrieve and modify data using the CCustomer class In previous chapters, you saw how these objects work together to handle database access By using Visual Studio NET's code-generation tools, you can rapidly create these components, allowing you to write simple and concise database access code Comments Two areas concerning automatically generated code require further... ExecuteScalar method, which returns this integer value to your Visual Basic code This requires dropping the Visual Studio NET-generated data adapter code, so you need to weigh this slight performance gain against the time needed to maintain manually generated code However, as you'll see in the following pages of this section, the code that Visual Studio NET generates is nothing you haven't read about... Country = ?, " & _ "Phone = ?, Fax = ? WHERE" (CustomerID = ?); SELECT CustomerID, " & _ "CompanyName, ContactName, ContactTitle, Address, City, Region, " & _ "PostalCode, Country, Phone, Fax FROM Customers " & _ "WHERE (CustomerID = ?)" ' add all of the parameters for the update command I have included only ' two parameters in this text Me.updateCustomer.Parameters.Add(New _ System.Data.OleDb.OleDbParameter("ContactName",... System.Data.DataRowVersion.Current, Nothing)) Me.updateCustomer.Parameters.Add(New System.Data.OleDb.OleDbParameter("Select2_CustomerID", System.Data.OleDb.OleDbType.WChar, 5, _ System.Data.ParameterDirection.Input, False, CType(0, Byte), CType(0, Byte), "CustomerID", _ System.Data.DataRowVersion.Current, Nothing)) End Sub This code is simple Visual Studio NET has created a data adapter based on the dsCustomers XSD, four Command . 9.3 Use Visual Studio .NET Tools to Speed Up Writing ADO .NET Code The code you've written up to this point doesn't do. SQL statements, Visual Studio .NET updates the Visual Basic code setting up their command objects. The SQL statements that Visual Studio .NET generates might

Ngày đăng: 14/12/2013, 20:16

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