NDP - ADO.NET 2.0
Viewing data in a DataTable

Contents

Introduction

We can get direct access if using the Rows and Columns collections on a DataTable. The DataTable.Select method allows us to filter.

Better is to use a DataView. Filter, sort, find, and you get proper handling of deleted row values.

Example code is in project DataSet\DtView.

Setup

Here is the setup for the DataTable we will be using.

        static DataSet ds;
        static DataTable items;


        private static void CreateDataTable()
        {
            ds = new DataSet("fred");

            items = new DataTable("Items");
            ds.Tables.Add(items);

            DataColumn dc;

            dc = new DataColumn();
            dc.ColumnName = "id";
            dc.DataType = typeof(Int32);
            dc.ReadOnly = true;
            dc.AllowDBNull = false;
            dc.Unique = true;
            dc.AutoIncrement = true;
            dc.AutoIncrementSeed = 100;
            dc.AutoIncrementStep = 10;
            items.Columns.Add(dc);

            dc = new DataColumn();
            dc.ColumnName = "name";
            dc.DataType = typeof(string);
            dc.AllowDBNull = false;
            dc.Unique = true;
            items.Columns.Add(dc);

            dc = new DataColumn();
            dc.ColumnName = "color";
            dc.DataType = typeof(string);
            dc.AllowDBNull = true;
            items.Columns.Add(dc);

            items.PrimaryKey = new DataColumn[] { items.Columns["id"] };
        }

        static string[] itemNames = { "widget", "freeble", "thingie", "whatzit", "geegaw" };
        static string[] itemColors = { "blue", "blue", "blue", "blue", "red" };

        private static void EnterInitialData()
        {

            DataRow row;

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

            // Make the initial rows Unchanged
            items.AcceptChanges();
        }

        private static void EditDataTable()
        {
            DataRow row;

            row = items.Rows[0];
            row.Delete();

            row = items.Rows[1];
            row["color"] = "teal";

            row = items.NewRow();
            row["name"] = "thingamabob";
            row["color"] = "green";
            items.Rows.Add(row);
        }

Find

The DataTable.Rows value is a DataRowCollection. THat collection has a Find method to use when searching for records by primary key.

        private static void FindData()
{
DataRow foundRow = items.Rows.Find(110);
if (foundRow == null)
Console.WriteLine("Didn't find it");
else
{
Console.WriteLine("Found a row");
PrintRow(foundRow); // see below
Console.WriteLine("------");
}
}

The overload of Find used above takes a single key value. If the table has a multi-field key, there is an overload that takes an object array.

 DataRow foundRow = dataTable.Find( new object[] { key1, key2, key3 } );

Select

The Select method of the DataTable allows you to specify several criteria:

DataRow[] rows = dt.Select(filter,sort,state);

There are overloads taking 0, 1, or 2 arguments that default the trailing parameters.

Member name Description Value
Added A new row.
4
CurrentRows Current rows including unchanged, new, and modified rows.
22
Deleted A deleted row.
8
ModifiedCurrent A current version, which is a modified version of original data (see ModifiedOriginal).
16
ModifiedOriginal The original version (although it has since been modified and is available as ModifiedCurrent).
32
None None.
0
OriginalRows Original rows including unchanged and deleted rows.
42
Unchanged An unchanged row.
2


Because of the possibility of seeing Deleted rows, some caution must be taken. I wrote the following method to display the values in a row:

        private static void PrintData(string p, DataRow[] rows)
        {
            Console.WriteLine("------");
            Console.WriteLine(p);
            foreach (DataRow row in rows)
                PrintRow(row);
            Console.WriteLine("------");

        }

        private static void PrintRow(DataRow row)
        {
            foreach (DataColumn col in row.Table.Columns)
                if (row.HasVersion(DataRowVersion.Default))
                    Console.Write("\t{0}", row[col]);
                else
                    Console.Write("\t{0}", row[col, DataRowVersion.Original]); // is deleted
            Console.WriteLine();
        }

Here are some calls to Select, with the output shown next to it.

items.Select()
110     freeble teal
120 thingie blue
130 whatzit blue
140 geegaw red
150 thingamabob green
items.Select("color='blue'")
120     thingie blue
130 whatzit blue
items.Select("color='blue'",
             "name DESC")
130     whatzit blue
120 thingie blue
items.Select("","",
   DataViewRowState.Added)
150     thingamabob     green
items.Select("","",
   DataViewRowState.CurrentRows)
110     freeble teal
120 thingie blue
130 whatzit blue
140 geegaw red
150 thingamabob green
items.Select("", "", 
   DataViewRowState.Deleted)
100     widget  blue
items.Select("", "", 
   DataViewRowState.ModifiedCurrent)
110     freeble teal
items.Select("", "", 
   DataViewRowState.ModifiedOriginal)
110     freeble teal
items.Select("", "", 
   DataViewRowState.OriginalRows)
100     widget  blue
110 freeble teal
120 thingie blue
130 whatzit blue
140 geegaw red
items.Select("", "", 
   DataViewRowState.Unchanged)
120     thingie blue
130 whatzit blue
140 geegaw red

You see no difference between ModifiedCurrent and ModifiedOriginal here; both select all Modified rows. You will see difference when these enum values are used in a DataView. See below.

DataViews

Basics

Properties

Property Description
RowFilter Specify a SQL WHERE clause to select rows.
RowStateFilter Specify a value to DataRowViewState to select which rows/values are seen.
Sort Specify a SQL ORDER BY clause to sort rows. An index will be created on these columns.
ApplyDefaultSort Set the Sort property to match the primary key field(s). Only works when the Sort property is null or the empty string.

Viewing data

DataViewRowState Description
CurrentRows The Current row version of all Unchanged, Added, and Modified rows.
Added The Current row version of all Added rows
Deleted The Original row version of all Deleted rows.
ModifiedCurrent The Current row version of all Modified rows.
ModifiedOriginal The Original row version of all Modified rows.
None No rows.
OriginalRows The Original row version of all Unchanged, Modified, and Deleted rows.
Unchanged The Current row version of all Unchanged rows.

Modifying data

Finding data

Example

And away we go. First, a few helper to write out things of interest.

        private static void PrintViewInfo(DataView view)
{
Console.WriteLine("View settings:");
Console.WriteLine(" AllowDelete: {0}", view.AllowDelete);
Console.WriteLine(" AllowEdit: {0}", view.AllowEdit);
Console.WriteLine(" AllowNew: {0}", view.AllowNew);
Console.WriteLine(" Filter: {0}", view.RowFilter);
Console.WriteLine(" State: {0}", view.RowStateFilter);
Console.WriteLine(" Sort: {0}, Default: {1}", view.Sort, view.ApplyDefaultSort);
} private static void PrintData(DataView view) { Console.WriteLine("------"); Console.WriteLine("Filter: {0}",view.RowFilter); Console.WriteLine("State: {0}",view.RowStateFilter); Console.WriteLine("Sort: {0}, Default: {1}",view.Sort,view.ApplyDefaultSort); foreach (DataRowView drv in view) PrintRow(drv); Console.WriteLine("------"); } private static void PrintRow(DataRowView row) { Console.Write("{0}\t",row.RowVersion); foreach (DataColumn col in row.DataView.Table.Columns) Console.Write("{0}\t", row[col.ColumnName]); Console.WriteLine(); }

Notice that we do not have to worry about the row version when using the [] indexing on a DataRowView.

Some code and some output:

Console.WriteLine("Default view from the table itself:");
PrintViewInfo(items.DefaultView);

Default view from the table itself:
View settings:
  AllowDelete: True
  AllowEdit:   True
  AllowNew:    True
  Filter:
  State:  CurrentRows
  Sort:   , Default: False
DataView view;

view = new DataView(items);

Console.WriteLine("Our view, default settings:");
PrintViewInfo(view);      
PrintData(view);
Our view, default settings:
View settings:
  AllowDelete: True
  AllowEdit:   True
  AllowNew:    True
  Filter:
  State:  CurrentRows
  Sort:   , Default: False
------
Filter:
State:  CurrentRows
Sort:   , Default: False
Current 110     freeble teal
Current 120     thingie blue
Current 130     whatzit blue
Current 140     geegaw  red
Current 150     thingamabob     green
------
Console.WriteLine("Setting filter and sort:");
view.RowFilter = "color='blue'";
view.RowStateFilter = DataViewRowState.CurrentRows;
view.Sort = "name DESC";
PrintData(view);
Setting filter and sort:
------
Filter: color='blue'
State:  CurrentRows
Sort:   name DESC, Default: False
Current 130     whatzit blue
Current 120     thingie blue
------
Console.WriteLine("You will see a difference between " +
   "ModifiedCurrent and ModifiedOriginal");
view.RowFilter = "";
view.Sort = "";
view.RowStateFilter = DataViewRowState.ModifiedCurrent;
PrintData(view);

view.RowStateFilter = DataViewRowState.ModifiedOriginal;
PrintData(view);
You will see a difference between 
   ModifiedCurrent and ModifiedOriginal
------
Filter:
State: ModifiedCurrent
Sort: , Default: False
Current 110 freeble teal
------
------
Filter:
State: ModifiedOriginal
Sort: , Default: False
Original 110 freeble blue
------
Console.WriteLine("Look at deleted");
view.RowFilter = string.Empty;
view.RowStateFilter = DataViewRowState.Deleted;
PrintData(view);
Look at deleted
------
Filter:
State:  Deleted
Sort:   , Default: False
Original        100     widget  blue
------
Console.WriteLine("Adding something via the view,"+
  " then viewing only added");
DataRowView newRow = view.AddNew();
newRow["color"] = "red";
newRow["name"] = "gadget";
newRow.EndEdit();
view.RowFilter = string.Empty;
view.RowStateFilter = DataViewRowState.Added;
PrintData(view);
Adding something via the view, then viewing only added
------
Filter:
State:  Added
Sort:   , Default: False
Current 150     thingamabob     green
Current 160     gadget  red
------
Console.WriteLine("Setting ApplyDefaultSort to true "+
  "does nothing if sort is set.");
view.RowFilter = string.Empty;
view.RowStateFilter = DataViewRowState.CurrentRows;
view.Sort = "color";
view.ApplyDefaultSort = true;
PrintData(view);
Setting ApplyDefaultSort to true 
   does nothing if sort is set.
------
Filter:
State:  CurrentRows
Sort:   color, Default: True
Current 120     thingie blue
Current 130     whatzit blue
Current 150     thingamabob     green
Current 140     geegaw  red
Current 160     gadget  red
Current 110     freeble teal
------
Console.WriteLine("Resetting Sort to empty");
view.ApplyDefaultSort = false;
view.Sort = string.Empty;
PrintData(view);
Resetting Sort to empty
------
Filter:
State:  CurrentRows
Sort:   , Default: False
Current 110     freeble teal
Current 120     thingie blue
Current 130     whatzit blue
Current 140     geegaw  red
Current 150     thingamabob     green
Current 160     gadget  red
------
Console.WriteLine("Applying default sort");
view.ApplyDefaultSort = true;
PrintData(view);
Applying default sort
------
Filter:
State:  CurrentRows
Sort:   id, Default: True
Current 110     freeble teal
Current 120     thingie blue
Current 130     whatzit blue
Current 140     geegaw  red
Current 150     thingamabob     green
Current 160     gadget  red
------
Console.WriteLine("All current rows, by color");
view.RowFilter = string.Empty;
view.RowStateFilter = DataViewRowState.CurrentRows;
view.ApplyDefaultSort = false;
view.Sort = "color";

PrintData(view);
All current rows, by color
------
Filter:
State:  CurrentRows
Sort:   color, Default: False
Current 120     thingie blue
Current 130     whatzit blue
Current 150     thingamabob     green
Current 140     geegaw  red
Current 160     gadget  red
Current 110     freeble teal
------
int index = view.Find("red");
Console.WriteLine("Found first red object at {0}", index);
Found first red object at 3
DataRowView[] rows = view.FindRows("blue");
Console.WriteLine("Blue rows");
foreach (DataRowView drv in rows)
    PrintRow(drv.Row); 
Blue rows
        120     thingie blue
        130     whatzit blue