Chapter 09 : ADO.NET: Datasets and Data Manipulation on Windows Forms

This chapter wraps up the discussion of ADO.NET by drilling down on two topics: datasets and programming data manipulation on a Windows form. The material in this chapter expands on earlier treatments of these topics. Specifically , Chapter 7 presented ADO.NET from the architectural and conceptual perspectives, and Chapter 8 highlighted a broad range of ADO.NET coding techniques. While this chapter concludes the set of chapters focusing on Windows Forms, it also demonstrates how to use ADO.NET techniques without going into much detail about coding issues.

There are three sections in this chapter. The first section carefully contrasts techniques for creating and using datasets. You learn exactly how various graphical techniques contrast with one another and how graphically created datasets can differ from datasets that you develop with your own code. In particular, the chapter contrasts typed datasets with untyped datasets and discusses how to create datasets containing multiple DataTable objects. The second section focuses on parent-child relationships between DataTable objects within a dataset. This section demonstrates how to instantiate and use these relationships to select a subset of child rows matching a parent row. In addition, the sample reveals how to process the rows in the parent and child DataTable object dynamically ”that is, based on inputs specified at run time. The third section is a case study application enabling the browsing, inserting, deleting, and updating of data in a Microsoft Access database from a Microsoft Windows application project. The case study systematically reviews all the elements of the application, including the Design view for the form, its operation, and the code behind all the events.

Creating and Using Datasets

You know from Chapter 7 that DataSet objects lie at the core of many ADO.NET applications. Datasets are one important factor underlying the improved scalability of Access databases via Microsoft Visual Basic .NET. As far back as Chapter 2, you learned how to create a dataset. Since that early introduction to the topic, this book has expanded its coverage of datasets in two significant ways. First, you learned more about the basic technique for creating a dataset in Chapter 2. Second, you learned other techniques for creating datasets (for example, in Chapter 7). This section takes a step back and contrasts three techniques for creating datasets and two varieties of datasets that you can use in your applications. In addition, the section closes by demonstrating one approach for instantiating multiple DataTable objects within a single dataset.

Three Ways to Make a Dataset

As you ve learned, a dataset is a collection of one or more DataTable objects. Each DataTable object can have one or more rows of data in its collection of DataRow objects, available through the DataTable object s Rows property. Many possible sources for the DataTable objects in a dataset exist, but Access developers will often use a table or query from an Access database. There are at least three approaches to creating a dataset with a DataTable object that relies on an Access database as its source.

Note  

All the samples for this chapter reside in the DatasetForms Windows project available with this book s sample files.

Dragging a Table or Query to a Windows Form

The first technique this book demonstrated for instantiating a DataSet object based on an Access database is dragging an Access table or view from Server Explorer to a Windows form. An Access view is a SELECT query with no parameters. Built-in code within Microsoft Visual Studio .NET automatically generates OleDbConnection and OleDbDataAdapter objects when you drag an Access table or view onto a Windows form. These objects appear in a tray below the form. If you right-click the OleDbDataAdapter object, you can choose Generate Dataset to create a new dataset or you can designate a previously existing dataset for the OleDbDataAdapter to reference. As you have learned, a data adapter can initially fill a DataTable object in a dataset as well as coordinate the contents of a DataTable object with an Access data source.

After you generate a dataset for a data adapter with the right-click menu, Visual Studio .NET adds an icon for the dataset to the tray below the form and to Solution Explorer. If you accept the default names for the first dataset in a Windows application project, the dataset in Solution Explorer will have the name DataSet1.xsd and the dataset in the tray will have the name DataSet11 . The dataset in Solution Explorer is an XML schema file that represents the contents of the dataset and the DataTable object corresponding to the Access table or query that you dragged to a Windows form. The DataSet11 icon in the tray below the form represents a variable pointing at the XML schema file. Your Visual Basic .NET custom application code should reference the DataSet11 variable. For example, you should reference the DataSet11 variable when invoking the Fill method for an OleDbDataAdapter object to populate a DataTable object in the dataset based on an Access data source.

If you double-click the DataSet1.xsd file in Solution Explorer, Visual Studio .NET opens a Design view of the DataSet1 dataset. Figure 9-1 depicts the schema for a DataTable object in DataSet1 based on the Order Details table from the Northwind database. The Visual Studio .NET builder that creates the DataTable object in the dataset orders the columns alphabetically by their name. By switching to XML view (see the button on the lower left of the DataSet1.xsd window), you can examine the XML schema code defining the dataset. Even without knowing XML schema language, you will readily recognize the code defining each column. You can rearrange the code to make the column names in Figure 9-1 appear in the same order as in the Design view for the Order Details table in the Northwind database.

click to expand
Figure 9-1: A Design view of the schema for the Order Details DataTable object in the DataSet1 dataset of the DatasetForms project

The following listing shows two excerpts from the XML view of the DataSet1 dataset in Figure 9-1. The top set of XML lines shows the order of the column designations as they initially appear. The bottom set of XML lines presents the order of the columns after minor editing for rearranging the order of column names in the DataSet view. You can reorder the lines with cut-and- paste operations. Simple editing like this can control the order in which columns appear in a DataGrid control based on a dataset.

 Initial column order: <xs:sequence> <xs:element name="Discount" type="xs:float" minOccurs="0" /> <xs:element name="OrderID" type="xs:int" /> <xs:element name="ProductID" type="xs:int" /> <xs:element name="Quantity" type="xs:short" minOccurs="0" /> <xs:element name="UnitPrice" type="xs:decimal" minOccurs="0" /> </xs:sequence> Adjusted column order: <xs:sequence> <xs:element name="OrderID" type="xs:int" /> <xs:element name="ProductID" type="xs:int" /> <xs:element name="UnitPrice" type="xs:decimal" minOccurs="0" /> <xs:element name="Quantity" type="xs:short" minOccurs="0" /> <xs:element name="Discount" type="xs:float" minOccurs="0" /> </xs:sequence> 

Dragging a Table or Query to the Dataset Designer

The preceding technique for generating a dataset automatically creates a one-to- one relationship for a dataset and DataTable object. If you drag over another Access table or query, you generate a new dataset with its own DataTable object. However, as you know, a single dataset can contain multiple DataTable objects. A second graphical technique for generating datasets facilitates creating multiple DataTable objects within a single dataset.

You can open the Dataset Designer by choosing Project, Add New Item, selecting the DataSet template, and clicking Open . If you accept the default name for the dataset and this dataset is the second one created in a project, Visual Studio .NET names the new dataset Dataset2 after the Dataset2.xsd file added to Solution Explorer. To add a DataTable object to the Dataset Designer, click the Server Explorer link if Server Explorer does not already appear. Then, drag one or more tables from Server Explorer to the Dataset Designer. To maintain comparability with the first dataset, I dragged the Order Details table to the Dataset Designer. If you then switch back to a Windows form and open the Toolbox, you can drag a DataSet icon from the Data tab in the Toolbox. This opens the Add Dataset dialog box. You will normally want to create a typed dataset based on the dataset that you created with the Project, Add New Item command. Use the drop-down box below the Typed Dataset radio button to select the dataset you are using. Figure 9-2 shows the dialog box with a selection of Dataset2 in the DatasetForms project. Clicking OK creates a new icon in the tray below the form, such as one named Dataset21 . The icon in the tray denotes a variable that points at a dataset created in the Dataset Designer.

click to expand
Figure 9-2: The Add Dataset dialog box lets you create a variable pointing at a dataset schema.

The preceding instructions create a typed dataset. A typed dataset is based on a specific dataset schema, such as Dataset2.xsd, and based on the System.Data.DataSet class. Notice that the Add Dataset dialog box allows you to create an untyped dataset. An untyped dataset is based on the System.Data.DataSet class, but it does not designate a specific schema. For example, an untyped dataset can have no assigned schema, or it can have a schema that you can change. If you select the Untyped Dataset radio button in Figure 9-2 and click OK, Visual Studio .NET declares a variable at a new instance of the System.Data.DataSet class. If this is the first untyped dataset in a project, the variable s default name is Dataset1, and it appears as an icon in the tray below the Windows form.

Programmatically Creating a Dataset

You can declare a dataset programmatically with a Dim statement or with an access modifier term , such as Friend . A dataset that you create in this way can be an untyped dataset. To instantiate a new empty untyped dataset, declare a variable based on the DataSet class from the System.Data namespace. This dataset will have an empty shell for an XML schema. You can populate the dataset with a DataTable object based on an Access table or query by using the Fill method for an OleDbDataAdapter object. After you populate the dataset, the schema for the dataset takes the form of the added DataTable object. You can add more tables to the dataset, and the dataset schema will automatically adjust. This behavior is characteristic of an untyped dataset.

The dataset that you create with the Dim statement will not have an .xsd file in Solution Explorer. Only typed datasets have a corresponding .xsd file in Solution Explorer. Instead, the dataset that you create programmatically with the Dim statement has a schema that you can change dynamically.

Understanding Datasets from the Forms Designer

Any dataset that you create graphically has code for it written by the Windows Form Designer. You can view this code by expanding the Windows Form Designer generated code region in the module behind a form. By examining this code, you can gain valuable insights about the datasets created by the Windows Form Designer and tips for your custom code creating datasets.

If you followed along as I created datasets in the previous section, you created three dataset variables graphically: DataSet11 , Dataset21 , and DataSet1 . The first two variables point at .xsd files. That is, these datasets point at the specific XML schema files. The third variable, DataSet1 , does not point at an .xsd file. Instead, DataSet1 points at the DataSet class in the System.Data namespace. The declarations in the DatasetForms project for the three dataset variables highlight these dependencies. For example, the following three lines in the DatasetForms project for Form1 appear in the Windows Form Designer generated code region. The lines are in the declaration area of the InitializeComponent procedure. Notice that DataSet11 is an instance of DataSet1 . Likewise, Dataset21 is an instance of Dataset2 . The DataSet1.xsd and Dataset2.xsd schema files act as class definitions. Both DataSet11 and Dataset21 are typed datasets. The following lines of code explicitly indicate the type for each dataset. These types, in turn , depend on the DataSet type in the System.Data namespace. DataSet1 is based on the generic DataSet class in the System.Data namespace.

 Me.DataSet11 = New DatasetForms.DataSet1()Me.Dataset21 = _ New DatasetForms.Dataset2() Me.DataSet1 = New System.Data.DataSet() 

The InitializeComponent procedure in the Windows Form Designer generated code region is a rich source of code samples for all the objects that you create and edit graphically for a form. The following lines from the procedure define properties for the objects denoted by the DataSet11 , Dataset21 , and DataSet1 variables. The Namespace property settings for the DataSet11 and Dataset21 objects point at .xsd files. The URLs specifically reference locations in the current project for the .xsd files. (As you have learned, the .xsd files reside within the root folder of the current project.) The DataSetName property settings for DataSet11 and Dataset 21 point at the schema names associated with the .xsd files. The DataSetName property for the DataSet1 variable points at NewDataSet within the DataSet type.

 ˜DataSet11 ˜ Me.DataSet11.DataSetName = "DataSet1" Me.DataSet11.Locale = New System.Globalization.CultureInfo("en-US") Me.DataSet11.Namespace = "http://www.tempuri.org/DataSet1.xsd" ˜ ˜Dataset21 ˜ Me.Dataset21.DataSetName = "Dataset2" Me.Dataset21.Locale = New System.Globalization.CultureInfo("en-US") Me.Dataset21.Namespace = "http://tempuri.org/Dataset2.xsd" ˜ ˜DataSet1 ˜Me.DataSet1.DataSetName = "NewDataSet" Me.DataSet1.Locale = New System.Globalization.CultureInfo("en-US") 

Custom Initialization Code for a Dataset

Custom ADO.NET initialization code will often appear in the module-level declaration area of the module behind a form and in the form load event. By defining ADO.NET variables in the module-level area, you make the variables available to multiple procedures within a declaration area. The form load procedure is a convenient place to run code (such as for populating a dataset) that might need to run just once during a session. Even if an operation must occur multiple times within a form session, running ADO.NET code in a form load event procedure can make data available when a form opens without any action ”such as clicking a button ”on the part of a user .

The following listing from the module behind Form1 in the DatasetForms project includes a couple of module-level variables and a form load event procedure. This listing demonstrates the typical kinds of ADO.NET tasks you can perform for these variables and the form load event procedure. The dap1 and das1 variable declarations instantiate two ADO.NET objects used throughout the application. The Form1_Load procedure assigns to the dap1 variable an OleDbDataAdapter object pointing at the Order Details table in the Northwind database. The second line in the procedure fills the Order Details DataTable object in the DataSet11 dataset. The DataTable object already exists before the Form1_Load procedure runs, but there is no data from the Northwind database in the object. The Fill method for the OleDbDataAdapter1 object populates the Order Details DataTable object with data. The Windows Form Designer automatically generates the OleDbDataAdapter1 object when a developer drags the Order Details table from Server Explorer to Form1 .

 ˜Declare and instantiate data adapter (dap1) ˜and dataset (das1) Dim dap1 As New OleDb.OleDbDataAdapter() Dim das1 As New System.Data.DataSet() Private Sub Form1_Load(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles MyBase.Load ˜Point data adapter at Order Details table ˜in the Northwind database dap1 = _ New OleDb.OleDbDataAdapter( _ "Select * FROM [Order Details]", _ "Provider=Microsoft.Jet.OLEDB.4.0;" & _ "Data Source=C:\Program Files\Microsoft Office\" & _ "Office10\Samples\Northwind.mdb") ˜Fill DataSet11 with local data table named ˜Order Details OleDbDataAdapter1.Fill(DataSet11, "Order Details") End Sub 

Schemas for Typed and Untyped Datasets

Although a dataset is an object for holding data, it is also an XML document. Just as a table in Access can have a Design view and a Datasheet view, an XML document has two views. The schema for an XML document describes the contents, and the matching file of data holds the rows of column values in a dataset. Some XML documents consolidate the schema and data in a single file, but in other cases, the schema and data reside in different files. By viewing the schema for a dataset, you can learn a lot about the structure of the data in a dataset. The discussion of schemas in this section does not deeply examine XML schema syntax conventions. The focus is on contrasting typed datasets with untyped ones. See the book s Chapter Appendix for material that focuses on XML schemas from the perspective of an Access developer building Visual Basic .NET solutions.

Note  

ADO.NET is especially attractive because it takes advantage of XML without forcing developers to know about XML syntax. Still, a working knowledge of XML will improve your ability to understand and use select features, such as typed datasets and the GetXmlSchema method.

Contrasting Schemas for Typed and Untyped Datasets

The click event procedure for Button1 in Form1 of the DatasetForms project contrasts the initial schemas for the DataSet11 and das1 datasets. As mentioned earlier, DataSet11 is a typed schema. Therefore, the schema for this dataset is the only one possible because the DataSet1 dataset, which is based on the DataSet1.xsd file, is the type for the dataset. In contrast, the das1 dataset is an untyped dataset. Its type is the generic DataSet type in the System.Data namespace. Therefore, its schema is not an integral part of its definition. The Button1_Click procedure shows the syntax for the GetXmlSchema method for a DataSet object. The method returns a text stream with the schema for a dataset that you can display in a message box.

 Private Sub Button1_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles Button1.Click ˜Display schema for DataSet11 dataset MsgBox(DataSet11.DataSetName() & vbCr & _ DataSet11.GetXmlSchema(), , _ "Typed Dataset Schema") ˜Display schema for das1 dataset MsgBox(das1.DataSetName() & vbCr & _ das1.GetXmlSchema(), , _ "Initial Untyped Dataset Schema") End Sub 

Figure 9-3 shows the first of two message boxes displayed by the Button1_Click procedure. This message box presents the schema for the DataSet11 dataset. My purpose in presenting the schema is not to get into a lengthy discussion of schema syntax conventions. However, the average database developer background should be enough for you to recognize the column definitions for the Order Details DataTable object in the dataset. These definitions occur between an opening and closing pair of sequence tags, namely < xs:sequence > and < /xs:sequence >. The column names within these tags do not appear in alphabetical order because they were manipulated, as described previously. Below the column definitions, another code block in the XML schema defines the primary key for the Order Details DataTable object. The primary key depends on two columns: OrderID and ProductID. This definition appears within a unique block with an attribute setting of PrimaryKey equal to true .

click to expand
Figure 9-3: The initial schema for the DataSet11 dataset in Form1 of the DatasetForms project

Figure 9-4 shows the second message box displayed by the Button1_Click procedure. This message box displays the default schema for a dataset that contains no DataTable objects. For the purpose of this discussion, the most important point is that no column definitions exist. The schema that appears in this message box corresponds to the schema for the NewDataSet dataset in the DataSet class definition within the System.Data namespace.

click to expand
Figure 9-4: The initial schema for the das1 dataset in Form1 of the DatasetForms project

Creating a Schema for an Untyped Dataset

You can indirectly design a schema for an untyped dataset, such as das1 , by filling the dataset with the contents of an Access table or query. Specifying a schema for an untyped dataset does not transform the dataset into a typed dataset. The type for a dataset depends on its type when you instantiate it ”not whether it has a schema. One important difference between schemas for typed datasets and those for untyped datasets is that you can change the schema for untyped datasets after instantiating a DataSet object. This is not possible for typed datasets because the dataset is an instance of the type used to declare it.

The Button2_Click procedure displays the schema for the das1 untyped dataset at two points in its evolution. The initial message box presents the schema immediately after filling the dataset with data from the Order Details table in the Northwind database. The procedure names the DataTable object in the das1 dataset OrderDetails . (Remember, you simplify many coding tasks by not using spaces in object names.) When you create a schema for a dataset with the Fill method, the .NET Framework does not create a primary key for the DataTable object in the dataset. Therefore, the procedure subsequently adds a primary key for the OrderDetails DataTable object. Then, the procedure displays the revised schema for the DataSet object. The PrimaryKey property for a DataTable object is a one-dimensional array of DataColumn objects. The length of the array increases by 1 for each column in a primary key.

 Private Sub Button2_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles Button2.Click ˜Fill das1 with Order Details table from the ˜Northwind database; name the DataTable object ˜OrderDetails dap1.Fill(das1, "OrderDetails") ˜Display schema for das1 dataset after ˜populating the dataset with a DataTable object MsgBox(das1.DataSetName() & vbCr & _ das1.GetXmlSchema(), , _ "Untyped Dataset Schema After Filling") ˜Assign a primary key to the OrderDetails ˜DataTable object based on the OrderID and ˜ProductID columns das1.Tables("OrderDetails").PrimaryKey = _ New DataColumn() _ {das1.Tables(0).Columns("OrderID"), _ das1.Tables(0).Columns("ProductID")} ˜Display schema for das1 dataset after adding ˜a primary key MsgBox(das1.DataSetName() & vbCr & _ das1.GetXmlSchema(), , _ "Untyped Dataset Schema " & _ "After Addition of Primary Key") End Sub 

Figures 9-5 and 9-6 show the two schemas displayed by the Button2_Click event procedure. The message box in Figure 9-5 includes the column definitions for the OrderDetails DataTable object. Notice that the minOccurs attribute setting for all columns is 0. A minOccurs value of 0 indicates that the designation of a column value for a row is optional. This absence of any required column values is one indication that the schema includes no primary key. A missing unique block is another indication that no primary key exists for the DataTable object. As mentioned earlier, a unique block with an attribute setting of PrimaryKey equal to true designates a collection of columns specifying a primary key.

click to expand
Figure 9-5: A schema without a primary key for the das1 dataset generated by the code behind Form1 of the DatasetForms project

The message box in Figure 9-6 is displayed after adding the definition of a primary key to the OrderDetails DataTable object. Notice the appearance of the unique block and the dropping of the minOccurs settings for the OrderID and ProductID columns.

click to expand
Figure 9-6: A schema with a primary key for the das1 dataset generated by the code behind Form1 of the DatasetForms project

Using IntelliSense for Typed Schemas

One advantage of typed datasets that some developers will appreciate is the availability of IntelliSense. Because the .NET Framework knows about the type for a typed dataset and the type is fixed, the .NET Framework can automatically display the appropriate members as you write expressions for the elements within a dataset. With an untyped dataset, you must use the Rows collection and explicitly use indexes to reference specific rows and columns in a DataTable object. The same goes for referencing the DataTable objects within a dataset. The .NET Framework uses IntelliSense to show the DataTable objects within a typed dataset, but with an untyped dataset, you have to designate an index for selecting a member from the Tables collection for a DataSet object.

The Button3_Click procedure contrasts the syntax for designating the OrderID column value in the first row of the first DataTable object in the DataSet11 and das1 datasets. The DataTable object has a slightly different name in each dataset, but in both cases, the Order Details table from the Northwind database populates the DataTable object. The procedure displays two message boxes to confirm that the value is the same for both expressions with different datasets. Because the DataSet11 dataset is a typed dataset, you can use dot notation to specify the table and column names within the DataSet11 dataset. Furthermore, Visual Basic .NET automatically presents a list of candidate items for selection after you type a period. The value in parentheses before the column name (OrderID) is a zero-based numeric index for the row number. The expression for the same column value appears in the das1 dataset next . Because this expression is for an untyped dataset, you must designate the table name as an index within the dataset s Tables collection; you can use either a numeric index value or a named index value. You specify the column within a row by the index value within the second set of parentheses after the designation of the Rows collection for a DataTable object. As in the syntax for the typed dataset, the first set of parentheses after the Rows collection is to designate a specific row in the DataTable object. You can use the syntax for the untyped dataset with a typed dataset, but the typed dataset syntax is not available for an untyped dataset.

Note  

I find using the untyped data syntax for datasets convenient because I have a common syntax that I can use for both typed and untyped datasets, which means I do not have to recall which kind of dataset I m using before figuring out which syntax to use. In addition, I find untyped datasets easier to develop and apply.

 Private Sub Button3_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles Button3.Click ˜Contrast the syntax for data access of OrderID column ˜value for first row with a typed dataset (DataSet11) ˜versus an untyped dataset (das1); IntelliSense ˜prompts for table and column names with a typed dataset MsgBox(DataSet11.Order_Details(0).OrderID.ToString) MsgBox(das1.Tables("OrderDetails"). _ Rows(0)("OrderID").ToString) End Sub 

Creating a Single Dataset with Two DataTable Objects

Nearly all the dataset samples in this book contain just one DataTable object per dataset. However, database developers can also design datasets with multiple DataTable objects. Multiple “ DataTable designs are often convenient because they permit your applications to logically require an interrelated set of two or more DataTable objects, such as objects based on the Orders and Order Details tables in the Northwind database.

This section demonstrates an approach to creating one dataset with two DataTable objects. The novel element when working with multiple DataTable objects in a dataset is programming a separate OleDbDataAdapter object for each DataTable object. Therefore, if you have a dataset with DataTable objects based on the Orders and Order Details tables from the Northwind database, you can program a separate data adapter to connect each DataTable object with its matching table in the database. You can readily point an OleDbDataAdapter object at a database object such as a table with a constructor that takes two string arguments: a SQL string expression that specifies a selection, and a connection string to a database from which the SQL string makes the selection. Either before or after defining your data adapters, you can specify a dataset based on the DataSet class in the System.Data namespace. Then, just invoke the Fill method for each OleDbDataAdapter object while specifying your dataset as the container for your DataTable object based on a separate Access table or query.

The Button4_Click procedure for Form1 demonstrates the syntax for populating a single dataset with two DataTable objects. The procedure begins by instantiating a pair of OleDbDataAdapter objects pointing at the Orders and Order Details tables from the Northwind database. Next, the procedure instantiates a single DataSet object, das1; this dataset overrides within the Button4_Click procedure the module-level das1 declaration at the top of the Form1 module. Then, the procedure invokes the Fill method for each data adapter. Each invocation of the Fill method designates the das1 dataset as the container for the DataTable object. The procedure concludes by displaying in a message box the count of rows for the Orders and OrderDetails DataTable objects. The string expression for the Prompt argument in the MsgBox function demonstrates how to return information about both DataTable objects within a single expression. See Figure 9-7 for the message generated by the procedure.


Figure 9-7: A message box from the Button4_Click procedure in Form1 that displays information about two DataTable objects in the same dataset
 Private Sub Button4_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles Button4.Click ˜Instantiate a pair of data adapters Dim dap1 As New OleDb.OleDbDataAdapter( _ "Select * FROM Orders", _ "Provider=Microsoft.Jet.OLEDB.4.0;" & _ "Data Source=C:\Program Files\Microsoft Office\" & _ "Office10\Samples\Northwind.mdb") Dim dap2 As New OleDb.OleDbDataAdapter( _ "Select * FROM [Order Details]", _ "Provider=Microsoft.Jet.OLEDB.4.0;" & _ "Data Source=C:\Program Files\Microsoft Office\" & _ "Office10\Samples\Northwind.mdb") ˜Instantiate a dataset Dim das1 As New System.Data.DataSet() ˜Use the data adapters to fill the dataset dap1.Fill(das1, "Orders") dap2.Fill(das1, "OrderDetails") ˜Return row count from each DataTable object MsgBox("Rows in " & _ das1.Tables(0).TableName & " is " & _ das1.Tables(0).Rows.Count.ToString & "." & _ vbCr & "Rows in " & _ das1.Tables(1).TableName & " is " & _ das1.Tables(1).Rows.Count.ToString & ".") End Sub 
 


Programming Microsoft Visual Basic. NET for Microsoft Access Databases
Programming Microsoft Visual Basic .NET for Microsoft Access Databases (Pro Developer)
ISBN: 0735618194
EAN: 2147483647
Year: 2006
Pages: 111
Authors: Rick Dobson

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