Skip to main content


The InitDataSet method creates the DataSet object. This object represents an in memory cache of data. InitDataSet configures it to mirror the structure of the Caché data. Here are some of its features:

  • Two DataTable objects: Contacts and PhoneNumbers, representing the Caché Provider.Contact and Provider.PhoneNumber tables. Uses conAdapter and phoneAdapter to fill Contacts and PhoneNumbers with data.

  • Each DataTable has a primary key defined on its ID column. In each case, the column represents the ID column of the corresponding Caché table. Defining a primary key for a DataTable enables the application to use the Find method to retrieve a row in the dataset using the ID value.

  • A parent-to-child relationship between the two data tables. This mirrors the relationship between Provider.Contact and Provider.PhoneNumber. Defining this relationship between the DataTable objects enables the application to use the GetChildRows method. This method, when invoked on a Contact DataRow, returns all of its child DataRow objects in PhoneNumbers.

  • An AutoIncrement column for the ID column of Contacts. Notice that the AutoIncrement starts at 0 and “increments” by -1. This value is essentially a dummy value. Since it is a primary key, a value must be assigned to the Contacts ID column. The value is overwritten by Caché when the application sends the data set data to Caché (when Update is invoked by the data set). Auto-incrementing with negative valuues ensures that there are no conflicts with the real ID values assigned by Caché.

  • Note that the ID column of PhoneNumbers cannot be an AutoIncrement column. The ID column of Provider.PhoneNumbers is not an integer, but a string. Caché row IDs for child tables have the form “x||y”.

Add the method body to the InitDataSet stub in PhoneForm.cs.

private void InitDataSet()
  ds = new DataSet();
  conAdapter.Fill(ds, "Contacts");
  phoneAdapter.Fill(ds, "PhoneNumbers");

  DataColumn contactColumn= ds.Tables["Contacts"].Columns["ID"];

  parent_to_child = ds.Relations.Add(ds.Tables["Contacts"].Columns["ID"], 
  ds.Tables["Contacts"].PrimaryKey = 
                  new DataColumn[] { ds.Tables["Contacts"].Columns["ID"] };
  ds.Tables["PhoneNumbers"].PrimaryKey = 
              new DataColumn[] { ds.Tables["PhoneNumbers"].Columns["ID"] };


When Fill is invoked on a data adapter, the adapter opens the connection to the database if it is not already opened. After performing the operation, the adapter leaves the connection in the state in which it was in before Fill was invoked. In this case, since the connection was closed before Fill was invoked the adapter closes the connection when it is finished.

For more information on defining AutoIncrement columns that represent AutoNumbered database columns read the AutoIncrement Columns discussion in the Updating DataSources with DataAdaptersOpens in a new tab section of the .NET Framework Developer's Guide.

FeedbackOpens in a new tab