Questions That Should Be Asked More Frequently

Using Strongly Typed DataSet Objects

Strongly typed DataSet objects simplify the development process, making it easier to write code to access and modify the contents of your DataSet. Let's look at a few examples that compare working with data in a standard untyped DataSet vs. working with a strongly typed DataSet.

Adding a Row

Each class for the DataTable objects in your DataSet offers two ways to add a new row to the DataTable. Calling New<TableName>Row returns a new strongly typed DataRow for your DataTable. You can then set values for columns in the row using properties of the strongly typed DataRow,as shown in the following code snippet.

Visual Basic .NET

Dim ds As New Chapter9() Dim tblCustomers As Chapter9.CustomersDataTable = ds.Customers Dim rowCustomer As Chapter9.CustomersRow                    rowCustomer = tblCustomers.NewCustomersRow() rowCustomer.CustomerID = "ABCDE" rowCustomer.CompanyName = "New Company" rowCustomer.ContactName = "New Contact" rowCustomer.Phone = "(800) 555-1212" tblCustomers.AddCustomersRow(rowCustomer) 'Instead of Dim rowCustomer As DataRow = tblCustomers.NewRow() rowCustomer("CustomerID") = "ABCDE" rowCustomer("CompanyName") = "New Company" rowCustomer("ContactName") = "New Contact" rowCustomer("Phone") = "(800) 555-1212" tblCustomers.Rows.Add(rowCustomer)

Visual C# .NET

Chapter9 ds = new Chapter9(); Chapter9.CustomersDataTable tblCustomers = ds.Customers; Chapter9.CustomersRow rowCustomer = tblCustomers.NewCustomersRow(); rowCustomer.CustomerID = "ABCDE"; rowCustomer.CompanyName = "New Company"; rowCustomer.ContactName = "New Contact"; rowCustomer.Phone = "(800) 555-1212"; tblCustomers.AddCustomersRow(rowCustomer); //Instead of DataRow rowCustomer = tblCustomers.NewRow(); rowCustomer["CustomerID"] = "ABCDE"; rowCustomer["CompanyName"] = "New Company"; rowCustomer["ContactName"] = "New Contact"; rowCustomer["Phone"] = "(800) 555-1212"; tblCustomers.Rows.Add(rowCustomer);

The benefits of using the strongly typed DataRow in this example are not clear when you see the code in print. Seeing this code in the Visual Studio .NET development environment will provide a better demonstration.

Figure 9-3 is a snapshot of the development environment. It shows that the columns of the strongly typed DataRow are easily accessible through statement completion. I was thrilled when Visual Basic introduced statement completion in version 5. However, if I made a mistake typing the name of a column in my Visual Basic 6 and ADO 2.x code, I would not discover that mistake until I ran my application. Strongly typed DataSet objects and statement completion can all but eliminate such problems in the development cycle.

Figure 9-3

Using a strongly typed DataSet in code in Visual Studio .NET

Like the Add method of the DataRowCollection, the Add<TableName>Row method of the strongly typed DataTable is overloaded. The following code snippet uses the Customers DataTable in the strongly typed DataSet we created earlier in the chapter.

Visual Basic .NET

Dim ds As New Chapter9() Dim tblCustomers As Chapter9.CustomersDataTable = ds.Customers tblCustomers.AddCustomersRow("ABCDE", "New Company", _                              "New Contact", "(800) 555-1212") 'Instead of tblCustomers.Rows.Add(New Object() {"ABCDE", "New Company", _                                     "New Contact", "(800) 555-1212"})

Visual C# .NET

Chapter9 ds = new Chapter9(); Chapter9.CustomersDataTable tblCustomers = ds.Customers; tblCustomers.AddCustomersRow("ABCDE", "New Company",                               "New Contact", "(800) 555-1212"); //Instead of tblCustomers.Rows.Add(new object[] {"ABCDE", "New Company",                                      "New Contact", "(800) 555-1212"});

Again, thanks to IntelliSense and statement completion, this is one of those features that looks more impressive as you write code. In the Visual Studio .NET development environment, the names of the parameters of the method appear as you type, so you don't have to jump back to other parts of your code to figure out the names and order of your columns.

Finding a Row

With a standard untyped DataSet, you can use the Find method of the DataTable object's Rows collection to locate a particular row based on its primary key value(s). Using that Find method can be confusing, especially if the DataTable has a multi-column primary key. For example, the Order Details table in the Northwind database uses the OrderID and ProductID columns as its primary key. Code that uses the Find method for a corresponding DataTable would therefore look like this:

Visual Basic .NET

Dim tblDetails As DataTable  Dim rowDetail As DataRow rowDetail = tblDetails.Find(New Object() {10245, 7})

Visual C# .NET

DataTable tblDetails;  DataRow rowDetail; rowDetail = tblDetails.Find(new object[] {10245, 7});

This code works, but it can be confusing to write. More important, it is difficult to read, which makes it challenging to maintain.

Each DataTable class in a strongly typed DataSet exposes its own Find method if the DataTable has a primary key defined. If we add a DataTable for the Order Details table to our strongly typed DataSet, we can replace the previous code snippet with this one, which is much easier to write and maintain.

Visual Basic .NET

Dim ds As New Chapter9() ... Dim tblDetails As Chapter9.Order_DetailsDataTable = ds.Order_Details Dim rowDetail As Chapter9.Order_DetailsRow rowDetail = tblDetails.FindByOrderIDProductID(10245, 7) If rowCustomer Is Nothing Then     Console.WriteLine("Row not found!") Else     Console.WriteLine("Found " & rowDetail.OrderID & " - " & _                       rowDetail.ProductID) End If

Visual C# .NET

Chapter9 ds = new Chapter9(); ... Chapter9.Order_DetailsDataTable tblDetails = ds.Order_Details; Chapter9.Order_DetailsRow rowDetail; rowDetail = tblDetails.FindByOrderIDProductID(10245, 7); if (rowDetail == null)     Console.WriteLine("Row not found!"); else     Console.WriteLine("Found " + rowDetail.OrderID.ToString() +                       " - " + rowDetail.ProductID.ToString());

Editing a Row

Editing rows in a strongly typed DataSet is similar to editing rows in a standard DataSet. You still have the option of using the BeginEdit, EndEdit, and CancelEdit methods. However, you can access the values of columns of the DataRow using properties of the strongly typed DataRow, as shown here.

Visual Basic .NET

Dim ds As New Chapter9() OleDbDataAdapter1.Fill(ds) Dim rowCustomer As Chapter9.CustomersRow = ds.Customers(0) rowCustomer.CompanyName = "Modified" 'Instead of rowCustomer("CompanyName") = "Modified"

Visual C# .NET

Chapter9 ds = new Chapter9(); OleDbDataAdapter1.Fill(ds); Chapter9.CustomersRow rowCustomer = ds.Customers[0]; rowCustomer.CompanyName = "Modified"; //Instead of rowCustomer["CompanyName"] = "Modified";

Working with Null Data

During the Visual Studio .NET beta, several newsgroup threads were concerned with null values. Many developers were confused about how to set the value in a column to null or how to determine whether a column contains a null value. In Chapter 6, you saw that you can use the DataRow object's IsNull function to check for null values and use System.Convert.DBNull to assign null values to columns.

Strongly typed DataSet objects also make working with null values easier. Each strongly typed DataRow also includes two methods per column—one to check whether the column contains a null value and one to set the column's value to null. The following code snippet works with the ContactName column for a row, so these methods are named IsContactNameNull and SetContactNameNull.

Visual Basic .NET

Dim ds As New Chapter9() OleDbDataAdapter1.Fill(ds) Dim rowCustomer As Chapter9.CustomersRow = ds.Customers(0) 'Check to see whether the ContactName property is Null. If rowCustomer.IsContactNameNull() Then     Console.WriteLine("Contact name is Null") Else     Console.WriteLine("Contact name: " & rowCustomer.ContactName) End If 'Set the ContactName property to Null. rowCustomer.SetContactNameNull() 'Instead of If rowCustomer.IsNull("ContactName") Then ... 'And rowCustomer("ContactName") = Convert.DBNull

Visual C# .NET

Chapter9 ds = new Chapter9(); OleDbDataAdapter1.Fill(ds); Chapter9.CustomersRow rowCustomer = ds.Customers[0]; //Check to see whether the ContactName property is Null. if (rowCustomer.IsContactNameNull()) then     Console.WriteLine("Contact name is Null"); else     Console.WriteLine("Contact name: " + rowCustomer.ContactName); //Set the ContactName property to Null. rowCustomer.SetContactNameNull(); //Instead of if (rowCustomer.IsNull("ContactName")) ... //And rowCustomer["ContactName"] = Convert.DBNull;

Working with Hierarchical Data

The DataRow object exposes two methods that let you navigate through your hierarchical data—GetChildRows and GetParentRow. These methods require you to supply either the name of the DataRelation you want to reference or the object itself.

If your strongly typed DataSet contains DataRelation objects, the XML Schema Definition Tool will add methods that let you navigate through your hierarchical data without having to specify the DataRelation or its name. In the strongly typed DataSet we built, we added a DataRelation to relate the Customers and Orders DataTable objects. When we saved the changes to the DataSet object's .xsd file, the XML Schema Definition Tool added a GetOrdersRows method to the strongly typed DataRow class for the Customers DataTable and a GetCustomersRow method to the strongly typed DataRow class for the Orders DataTable.

The following code snippet uses the GetOrdersRows method to display all customers as well as the orders for each customer.

Visual Basic .NET

Dim ds As New Chapter9() OleDbDataAdapter1.Fill(ds) OleDbDataAdapter2.Fill(ds) Dim rowCustomer As Chapter9.CustomersRow Dim rowOrder As Chapter9.OrdersRow For Each rowCustomer In ds.Customers     Console.WriteLine("Orders for " & rowCustomer.CompanyName)     For Each rowOrder In rowCustomer.GetOrdersRows()         Console.WriteLine(vbTab & rowOrder.OrderID & _                           " - " & rowOrder.OrderDate)     Next rowOrder Next rowCustomer 'Instead of Dim rowCustomer, rowOrder As DataRow For Each rowCustomer In ds.Tables("Customers").Rows     Console.WriteLine("Orders for " & rowCustomer("CompanyName"))     For Each rowOrder In rowCustomer.GetChildRows("CustomersOrders")         ...

Visual C# .NET

Chapter9 ds = new Chapter9(); OleDbDataAdapter1.Fill(ds); OleDbDataAdapter2.Fill(ds); CustomersDataTable tblCustomers = ds.Customers; CustomersRow rowCustomer = tblCustomers[0]; foreach (Chapter9.CustomersRow rowOrder           in ds.Tables["Customers"].Rows) {     Console.WriteLine("Orders for " + rowCustomer.CompanyName);     foreach (Chapter9.OrdersRow rowOrder               in rowCustomer.GetOrdersRows())         Console.WriteLine("\t" + rowOrder.OrderID.ToString() + _                           " - " + rowOrder.OrderDate.ToString()); } //Instead of foreach (DataRow rowCustomer in ds.Tables["Customers"].Rows) {     Console.WriteLine("Orders for " + rowCustomer["CompanyName"]);     foreach (DataRow rowOrder in               rowCustomer.GetChildRows("CustomersOrders"))     ... }

Other DataSet, DataTable, and DataRow Features

The classes that the XML Schema Definition Tool generates are derived from the DataSet, DataTable, and DataRow classes. This means you can also treat the classes as their untyped counterparts.

For example, the strongly typed DataSet classes do not have their own methods for reading and writing XML data and schema information. But because the classes are derived from the DataSet class, they still expose methods such as ReadXml and WriteXml. So for all other tasks, such as using a DataAdapter to retrieve data or submit changes, you can treat the strongly typed DataSet just like any other DataSet.



Microsoft ADO. NET Core Reference
Microsoft ADO.NET (Core Reference) (PRO-Developer)
ISBN: 0735614237
EAN: 2147483647
Year: 2002
Pages: 104
Authors: David Sceppa

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net