NDP - ADO.NET 2.0
DataTable basics

Contents

Defining a schema

Adding rows

Here is how to add rows to a table.

static string[] itemNames = { "widget",  "freeble", "thingie", 
                              "whatzit", "doodad",  "hack",   "munge" };
static string[] itemColors = { "red",    "blue",    "blue", 
                               "red",    "green",   "green",  "green" };

static string[] ownerNames = { "fred",   "fred",   "fred", 
                               "ted",    "ted",    "ted" };
static string[] ownedNames = { "widget", "freeble", "thingie", 
                               "widget", "freeble", "thingie" };

private static void PopulateTables()
{
    Dictionary<string,int> idMap = new Dictionary<string,int>();

    DataRow row;

	// adding item definitions
    for ( int i=0; i<itemNames.Length; ++i )
    {
        row = items.NewRow();
        row["name"] = itemNames[i];
        row["color"] = itemColors[i];
        items.Rows.Add(row);

        idMap[(string)row["name"]] = (int)row["id"];
    }

    Random rnd = new Random();

	// adding inventory records
    for ( int i = 0; i<ownerNames.Length; ++i )
    {
        row = inventory.NewRow();
        row["owner"] = ownerNames[i];
        row["itemId"] = idMap[ownedNames[i]];
        row["qty"] = rnd.Next(1, 10);
        row["price"] = new decimal(rnd.Next(50, 1000) / 100.0);
        inventory.Rows.Add(row);
    } 
}

Don't get thrown off by the use of the Dictionary. When we are adding rows to the items table, we generate ids for the items. We use idMap to store the relation between item names and item ids. When we then build the inventory table, we need to create the foreign key reference from an inventory row back to an item. Because our arrays of source data use item names, we use the dictionary to map the name to the id that is needed for the foriegn key reference.

Here is how to access rows from a table:

Constraints

Unique constraints

Foreign key constraints

private static void AddTableConstraint()
{
    ForeignKeyConstraint fk = new ForeignKeyConstraint("FK_Item_Inventory",
        items.Columns["id"],
        inventory.Columns["itemId"]);

    fk.DeleteRule = Rule.Cascade;
    fk.UpdateRule = Rule.SetNull;
    fk.AcceptRejectRule = AcceptRejectRule.Cascade;

    inventory.Constraints.Add(fk);
}
Rule Description
Cascade Deletes or updates related rows. This is the default.
SetNull Sets values in the related rows to DBNull.
SetDefault Sets values in related rows to the default value.
None Specifies that no action be taken on related rows.

 

Member name Description
Cascade Changes are cascaded across the relationship.
None No action occurs (default).

Relations

private static void AddRelation()
{
    DataRelation rel = new DataRelation("Item_Inventory",
        items.Columns["id"],
        inventory.Columns["itemId"]);
            
    ds.Relations.Add(rel);
          
    rel.ChildKeyConstraint.AcceptRejectRule = AcceptRejectRule.Cascade;
    rel.ChildKeyConstraint.DeleteRule = Rule.Cascade;
    rel.ChildKeyConstraint.UpdateRule = Rule.SetNull;
}

DataSet info

private static void PrintDataSetInfo(DataSet ds)
{
    Console.WriteLine("DataSet {0}: enforceConstraints = {1}", 
                      ds.DataSetName, ds.EnforceConstraints);

    Console.Write(" -- {0} tables: ", ds.Tables.Count);

    foreach (DataTable dt in ds.Tables)
        Console.Write("{0}, ", dt.TableName);
    Console.WriteLine();

    Console.Write(" -- {0} relations: ", ds.Relations.Count);

    foreach (DataRelation dr in ds.Relations)
        Console.Write("[{0}: {1} -> {2}], ", 
                      dr.RelationName,dr.ParentTable.TableName,dr.ChildTable.TableName);
    Console.WriteLine();
}