|
Overview
ADO.NET implements three basic forms to locate Rows - The Find
method as applied to the Rows collection, the Find method as applied to the DataView
object and the Contains method as applied to the Rows collection.
DataRowCollection Find and Contains
Method
The DataRowCollection is a major component of the
DataTable. While the DataColumnCollection defines the schema of the
table, the DataRowCollection contains the actual data for the table, where each
DataRow in the DataRowCollection represents a single row.
You can call the Add and Remove methods to insert and delete
DataRow objects from the DataRowCollection. You can also call the Find method
to search for DataRow objects that contain specific values in primary key columns,
and the Contains method to search character-based data for single words or
phrases.
DataView Find and FindRows Method
Using the Find and FindRows methods of the DataView, you can
search for rows according to their sort key values. The case-sensitivity of search
values in the Find and FindRows methods is determined by the CaseSensitive property
of the underlying DataTable. Search values must match existing sort key values in
their entirety in order to return a result.
The Rows Collection Find Method
Similar to the DataTable Select method, the Rows collection Find
method returns a DataRow object - in this case a single row instead of an
array. This method requires
that you set the Primary Key property before using it. If you don't, you will
trip a trappable exception.
Setting the PrimaryKey Property
Whem you execute a query that executes a stored procedure, ADO.NET
is not likely to discover and set the Primary Key for you. This means you'll probably
have to set it manually - at least most of the time. The following example
illustrates setting the Primary Key Property when there are two columns in the
Primary Key:
// Setting the Primary Key when there
are
// two columns in the Primary Key.
DataColumn[] colPk = new DataColumn[2];
colPk[0] = dsOrderItem.Tables[0].Columns["CustomerID"];
colPk[1] = dsOrderItem.Tables[0].Columns["OrderID"];
dsOrderItem.Tables[0].PrimaryKey = colPk;
The Rows.Find Method
After the Primary Key is set, using the Rows collection Find
method is fairly straightforward. The following example sets up and executes the Find
method against a Rows collection. Find returns a DataRow object based on the Primary
Key passwd as an argument.
The DataView Object's Find Method
The DataView object's Find method could care less abaout the
Primary Key. The Find method returns an integer with the index of the DataRowView
that matches the search criteria. If more than one row matches the search
criteria, only the index of the first matching DataRowView is returned. If no match
is found, Find returns -1.
To return search results that match multiple rows, you can use the
FindRows method. FindRows works just like the Find method, except that it returns a
DataRowView array that references all matching rows in the DataView. If no matches
are found, the DataRowView array will be empty.
To use the Find or FindRows methods you must specify a sort
order either by setting ApplyDefaultSort to true or by using the Sort
property. If no sort order is specified, an exception is thrown.
The following Example shows the use of the Find Method for both
the Rows Collection and DataView.
using System;
using System.Diagnostics;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Data.SqlClient;
namespace RowsAndDataViewFind
{
public class FindDemo : System.Windows.Forms.Form
{
private SqlConnection cn;
private SqlCommand cmd;
private SqlDataAdapter da;
private DataSet ds;
internal System.Windows.Forms.TextBox
txtFoundRow;
internal System.Windows.Forms.TextBox
txtFindArg;
internal System.Windows.Forms.Button
btnFind;
internal System.Windows.Forms.Button
btnFindRow;
internal System.Windows.Forms.DataGrid
DataGrid;
private System.Windows.Forms.Label
lbl_enter;
private System.Windows.Forms.Label
lbl_showrow;
private System.ComponentModel.Container
components = null;
public FindDemo()
{
try
{
InitializeComponent();
// Connect to Database and create Controls
cn = new SqlConnection(
"server=xeon;database=northwind;uid=sa;pwd=manager");
cmd = new SqlCommand("Select * from customers",cn);
cmd.CommandType = CommandType.Text;
da = new SqlDataAdapter(cmd);
ds = new DataSet();
RunQuery();
}
catch(Exception
ex)
{
MessageBox.Show(ex.ToString());
}
}
// Fill DataGrid with Data
private void RunQuery()
{
try
{
DataColumn[] dcPk = new DataColumn[1];
da.Fill(ds, "Customers");
// Set Primary Key
dcPk[0] = ds.Tables["Customers"].Columns["CustomerID"];
ds.Tables["Customers"].PrimaryKey = dcPk;
// Set Default Sort
ds.Tables[0].DefaultView.Sort = "CustomerID";
DataGrid.DataSource = ds.Tables[0];
}
catch (Exception
ex)
{
MessageBox.Show(ex.ToString());
Debug.WriteLine(ex.ToString());
}
}
// Finds a row in
the DataView by the specified sort key value
private void btnFind_Click(object sender,
System.EventArgs e)
{
try
{
int intRow;
// Finds the row specified in txtFindArg
intRow = ds.Tables[0].DefaultView.Find(txtFindArg.Text);
Debug.WriteLine(intRow);
if (intRow == -1)
{
MessageBox.Show("No PK matches " + txtFindArg.Text);
}
else
{
// Jump to the Row and select it
DataGrid.CurrentRowIndex = intRow;
DataGrid.Select(intRow);
}
}
catch(Exception
ex)
{
MessageBox.Show(ex.ToString());
}
}
// Most
applications that consume data need to access specific
// records that satisfy some kind of
criteria. In order to find
// a particular row in a dataset you
invoke the Find Method of
// the DataRowCollection. If the primary
key exists, a DataRow
// object is returned. If the primary key
cannot be found, a null
// value is returned.
private void btnFindRow_Click(object
sender, System.EventArgs e)
{
try
{
DataRow drFound;
// Find the Row specified in txtFindArg
drFound = ds.Tables[0].Rows.Find(txtFindArg.Text);
if (drFound == null)
{
MessageBox.Show("No PK matches " + txtFindArg.Text);
}
else
{
txtFoundRow.Text = drFound[0].ToString() + ", " +
drFound[1].ToString() + ", " +
drFound[2].ToString();
}
}
catch(Exception
ex)
{
MessageBox.Show(ex.ToString());
Debug.WriteLine(ex.ToString());
}
}
....
....
[STAThread]
static void Main()
{
Application.Run(new FindDemo());
}
}
}
The Rows Collection Contains Method
Another way to locate a row based on your DataTable object's
Primary Key property is to use the Rows collection Contains method. This method works
very much like the Find method in that it expects you to set the Primary Key
Property. However instead of returning a DataRow, the Contains method simply returns
a Boolean - TRUE, if the Row is found and FALSE if not.
The following example shows the use of the Contains and Remove
Methods.
using System;
using System.Diagnostics;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Data.SqlClient;
namespace RowsContain {
public class ContainAndRemove : System.Windows.Forms.Form {
private SqlConnection cn;
private SqlCommand cmd;
private SqlDataAdapter da;
private DataSet ds;
private DataRow rowFound;
internal System.Windows.Forms.Button
btnSearch;
internal System.Windows.Forms.TextBox
txtSearchFor;
internal System.Windows.Forms.Button
btnRemoveRow;
internal System.Windows.Forms.DataGrid
DataGrid;
internal System.Windows.Forms.Label
lblSearch;
private System.ComponentModel.Container
components = null;
public ContainAndRemove() {
try{
InitializeComponent();
// Connect to the Database
cn = new SqlConnection(
"server=xeon;database=northwind;uid=sa;pwd=manager");
cmd = new SqlCommand(
"SELECT * FROM Customers ORDER BY CustomerID", cn);
da= new SqlDataAdapter(cmd);
ds= new DataSet();
da.Fill(ds);
DataGrid.PreferredColumnWidth = 200;
DataGrid.DataSource = ds.Tables[0];
}
catch(Exception
ex) {
Debug.WriteLine(ex.ToString());
MessageBox.Show(ex.ToString());
}
}
// Gets a value
indicating whether the primary key column(s)
// of any row in the collection contains
the specified value.
private void btnSearch_Click(object
sender, System.EventArgs e)
{
try {
DataTable tb = ds.Tables[0];
int intRow;
// Set Primary Key and Sort Order
DataColumn[] dcolPk = new DataColumn[1];
dcolPk[0] = tb.Columns["CustomerID"];
tb.PrimaryKey = dcolPk;
tb.DefaultView.Sort = "CustomerID";
// Rows.Contains returns TRUE or FALSE
if (tb.Rows.Contains(txtSearchFor.Text)) {
// At least one row matches primary key
rowFound = tb.Rows.Find(txtSearchFor.Text);
intRow = ds.Tables[0].DefaultView.Find(txtSearchFor.Text);
if ((rowFound == null) | (intRow == -1)) {
MessageBox.Show("Could not find row ");
}
else {
DataGrid.CurrentRowIndex = intRow;
DataGrid.Select(intRow);
}
}
else {
MessageBox.Show("No row found that matches " + txtSearchFor.Text);
}
}
catch(Exception
ex) {
Debug.WriteLine(ex.ToString());
MessageBox.Show(ex.ToString());
}
}
// When a row is
removed, all data in that row is lost. You can
// also call the Delete method of the
DataRow class to simply mark
// a row for removal. Calling Remove is
the same as calling Delete
// and then calling AcceptChanges.
// You can also use the Clear method to
remove all members of
// the collection at once.
private void btnRemoveRow_Click(object
sender, System.EventArgs e)
{
try {
ds.Tables[0].Rows.Remove(rowFound);
}
catch(Exception
ex) {
Debug.WriteLine(ex.ToString());
MessageBox.Show(ex.ToString());
}
}
....
....
[STAThread]
static void Main() {
Application.Run(new ContainAndRemove());
}
}
}
|