C# Code Examples

Quick jump to:
DataSet
DataView
DataReader
WebControls
WebService
Transaction
Tips of any kind

DataSet etc.

// Access data fields:

// Not strongly typed:
theDataTable.Rows[rowNum]["FirstName"]
theDataRow["FirstName"]

// Strongly typed:
theDataTable.Rows[rowNum].Field<string>("FirstName")
theDataRow.Field<string>("FirstName")

//*******************************
// Scan rows and columns of a DataTable:

private void PrintValues(DataTable aDataTable)
{
	// Scan rows:
	foreach (DataRow currRow in aDataTable.Rows)
	{
 		// Scan columns:  
		foreach (DataColumn currCol in aDataTable.Columns)
		{
			Console.WriteLine(currRow[currCol]);
		}
 	}
}

//*******************************
// RowChanging, RowChanged, ColumnChanging and ColumnChanged events of DataTable:

using System;
using System.Data;

namespace ZuskinCom
{
class DataTester
{
    DataTable dtCustomers;

    #region METHODS

    public void DTBuild()
    {
       // Create table:
       dtCustomers = new DataTable("Customers");

       // Add columns:
       dtCustomers.Columns.Add("id", typeof(int));
       dtCustomers.Columns.Add("name", typeof(string));

       // Define Primary Key:
       dtCustomers.Columns["id"].Unique = true;
       dtCustomers.PrimaryKey = new DataColumn[] { dtCustomers.Columns["id"] };

       // Add RowChanging event handler to the table:
       dtCustomers.RowChanging += new DataRowChangeEventHandler(Row_Changing);

       // Add RowChanged event handler to the table:
       dtCustomers.RowChanged += new DataRowChangeEventHandler(Row_Changed);

       // Add ColumnChanging handler to the table:
       dtCustomers.ColumnChanging += new DataColumnChangeEventHandler(Column_Changing);

       // Add ColumnChanged event handler to the table:
       dtCustomers.ColumnChanged += new DataColumnChangeEventHandler(Column_Changed);
    } // end of class DataTester

    public void RowsAdd(int id)
    {
       int x;

       // Add rows:
       for (x = 0; x < id; x++)
       {
           dtCustomers.Rows.Add(new object[] { x, string.Format("customer{0}", x) });
       }
       dtCustomers.AcceptChanges();
    } // end of RowsAdd()

    public void RowsChange()
    {
       // Change value of column 'name' for each row (like 'customer5' ==>> 'vip customer5'):
       foreach (DataRow row in dtCustomers.Rows)
       {
           row["name"] = string.Format("vip {0}", row["id"]);
       }
    } // end of RowsChange()

    public void PrintDataTableColumnInfo()
    {
       // Use a DataTable object's DataColumnCollection:
       DataColumnCollection columns = dtCustomers.Columns;

       // Print the ColumnName and DataType for each column:
       foreach (DataColumn column in columns)
       {
          Console.WriteLine("ColumnName = '{0}', DataType = {1}", column.ColumnName, column.DataType);
       }
       Console.ReadLine();
    } // end of PrintDataTableColumnInfo()

    #endregion

    #region EVENT HANDLERS

    private static void Row_Changing(object sender, DataRowChangeEventArgs e)
    {
       Console.WriteLine("Row_Changing Event: name={0}; action={1}", e.Row["name"], e.Action);
    }

    private static void Row_Changed(object sender, DataRowChangeEventArgs e)
    {
       Console.WriteLine("Row_Changed Event: name={0}; action={1}", e.Row["name"], e.Action);
    }

    private static void Column_Changing(object sender, DataColumnChangeEventArgs e)
    {
       Console.WriteLine("Column_Changing Event: name={0}; Column={1}; proposed name={2}",
                          e.Row["name"],
                          e.Column.ColumnName,
                          e.ProposedValue);
    }

    private static void Column_Changed(object sender, DataColumnChangeEventArgs e)
    {
       Console.WriteLine("Column_Changed Event: name={0}; Column={1}; proposed name={2}",
                          e.Row["name"],
                          e.Column.ColumnName,
                          e.ProposedValue);
    }

    #endregion
 }

class Program
{
   static void Main(string[] args)
   {
      DataTester dt = new DataTester();
      dt.DTBuild();
      dt.RowsAdd(1);
      dt.RowsChange();
      dt.PrintDataTableColumnInfo();
      Console.ReadLine();
   }
}
 }

//*******************************
// DataSet в свободном полете (like external DW):

DataSet    ds = new DataSet(); // Пустой объект
DataTable  dt = new DataTable(); // Пустая таблица
DataColumn colShips = new DataColumn("Ships");

ds.Tables.Add(dt);
ds.Tables[0].Columns.Add(colShips);

// Прочие столбцы подсоединяются аналогичным образом. Таким образом формируются поля данных таблицы.
// Внимание! После того как определена структура таблицы, то есть определены ВСЕ СТОЛБЦЫ таблицы,
// от имени этой конкретной таблицы порождается объект-строка. Этот объект сразу располагается
// непосредственно в таблице. Для каждой определенной таблицы метод NewRow() порождает строку
// (последовательность значений соответствующего типа). Для непосредственного редактирования вновь созданной
// строки запоминается ее ссылка. Работать со строкой через эту ссылку проще, чем с массивом строк таблицы.
DataRow dr = ds.Tables[0].NewRow();

// Остается заполнить строку таблицы содержательной информацией. При этом может быть использован любой
// источник данных. В данном примере предполагается наличие объекта типа ArrayList с именем ShipCollection.
for (int i = 0; i < ShipCollection.Count; i++)
{
   dr.Item[Counter] = ShipCollection[i];
} 

// Заполненный объект - представитель класса DataRow добавляется 
// к набору Rowsкласса DataTable.
ds.Tables[0].Rows.Add(dr);

//*******************************
// Working with DataSet, DataTable, DataRow and DataColumn:

 using System;
 using System.Data;

 namespace mergeTest
 {
 class Class1
 {
 static void Main(string[] args)
 {
 DataSet       ds = new DataSet("myDataSet");
 DataTable     dtItems = new DataTable("Items");
 DataColumn    colId = new DataColumn("id", Type.GetType("System.Int32"));
 DataColumn    colItem= new DataColumn("Item", Type.GetType("System.Int32"));
 DataColumn[]  colPrimaryKeyArray = new DataColumn[1];
 DataRow       dr;
 
 colId.AutoIncrement = true;
 
 dtItems.Columns.Add(colId);
 dtItems.Columns.Add(itemDataColumn);

 colPrimaryKeyArray[0]= colId;
 dtItems.PrimaryKey = colPrimaryKeyArray;
 
 ds.Tables.Add(dtItems);

// Add 10 rows to the table:
 for(int i = 0; i < 10; i++)
 {
    dr = dtItems.NewRow();
    dr["Item"] = i;
    dtItems.Rows.Add(dr);
 }

 // Принять изменения. Так производится обновление DataSet'а. Сведения о новых изменениях и добавлениях
 // будут фиксироваться вплоть до нового обновления:
 ds.AcceptChanges();
 PrintValues(ds, "Original values");

 // Изменение значения в первых 3 строках:
 dtItems.Rows[0]["Item"]= 50;
 dtItems.Rows[1]["Item"]= 111;
 dtItems.Rows[2]["Item"]= 111;

 // Добавление еще одной строки. Судя по всему, значение первого столбца устанавливается автоматически.
 // Это ключевое поле со значением порядкового номера строки:
 dr = dtItems.NewRow();
 dr["Item"] = 74;
 dtItems.Rows.Add(dr);

 // Объявляем ссылку для создания временного DataSet. 
 DataSet tempDataSet;

 // ДЕКЛАРАЦИЯ О НАМЕРЕНИЯХ КОНТРОЛЯ ЗА КОРРЕКТНОСТЬЮ ЗНАЧЕНИЙ СТРОКИ. 
 // Вот так добавляется свойство, содержащее строку для описания 
 // ошибки в значении. Наш DataSet содержит одну строку с описанием.
 // Это всего лишь указание на то обстоятельство, что МЫ САМИ 
 // обязались осуществлять
 // некоторую деятельность по проверке чего-либо. Чтобы не забыть, 
 // в чем проблема,
 // описание возможной ошибки (в свободной форме!) добавляем 
 // в свойства строки,
 // значения которой требуют проверки.
 dtItems.Rows[0].RowError = "over 100 (ЙЦУКЕН!)";
 dtItems.Rows[1].RowError = "over 100 (Stupid ERROR!)";
 dtItems.Rows[2].RowError = "over 100 (Ну и дела!)";
 // Но одно дело – декларировать намерения, а другое – осуществлять контроль.
 // Проблема проверки корректности значения – наша личная проблема.
 // Однако о наших намерениях контроля за значениями становится 
 // известно объекту – представителю DataSet!

 PrintValues(ds, "Modified and New Values");

 // Мы вроде бы согласились проводить контроль значений.
 // Даже декларировали некий принцип проверки. 
 // Однако ничего само собой не происходит.
 // Так вот,
 //
 // ЕСЛИ В ТАБЛИЦУ БЫЛИ ДОБАВЛЕНЫ СТРОКИ ИЛИ ИЗМЕНЕНЫ ЗНАЧЕНИЯ СТРОК
 // И
 // МЫ ОБЯЗАЛИСЬ КОНТРОЛИРОВАТЬ ЗНАЧЕНИЯ СТРОК В ТАБЛИЦЕ,
 //
 // то самое время организовать эту проверку...
 // Критерий правильности значений, естественно, наш!
 // Алгоритмы проверки – тоже НАШИ!
 // Единственное, чем нам может помочь ADO .NET, – это выделить
 // подмножество строк таблицы,
 // которые были добавлены или модифицированы со времени последнего
 // обновления нашего объекта - представителя DataSet'а,

 if(ds.HasChanges(DataRowState.Modified | DataRowState.Added) & ds.HasErrors)
 {
 // И для этого мы воспользуемся методом, который позволяет обеспечить
 // выделение подмножества добавленных и
 // модифицированных строк в новый объект DataSet'а.
 // Use GetChanges to extract subset.
 tempDataSet = ds.GetChanges(DataRowState.Modified|DataRowState.Added);
 PrintValues(tempDataSet, "Subset values");

 // Insert code to reconcile errors. In this case, we'll reject changes.
 // Вот, собственно, код проверки. Все делается своими руками.
 foreach(DataTable tbl in tempDataSet.Tables)
 {
    if (!tbl.HasErrors) continue;
    foreach(DataRow row in tbl.Rows)
    {
       // Выделенное подмножество проверяем на наличие
       // ошибочного значения (для нас все, что больше 100, – уже ошибка!) 
       Console.Write(row["Item"] + "  ");
       if((int)row["Item", DataRowVersion.Current] > 100)
       {
          Console.WriteLine("Error! – " + row.RowError); // Находим ошибку в строке, сообщаем о ней
          row.RejectChanges(); // Возвращаем старое значение...
          row.ClearErrors(); // Отменяем значение свойства-уведомителя о возможных ошибках для строки
       }
       else
         Console.WriteLine("OK.");
    }
 }

 PrintValues(tempDataSet, "Reconciled subset values");

 // Сливаем измененные и откорректированные строки в основной объект – DataSet
 // Merge changes back to first DataSet.
 ds.Merge(tempDataSet);

 PrintValues(ds, "Merged Values");
 }
 }

 // А это всего лишь вывод содержимого DataSet'а.
 private static void PrintValues(DataSet ds, string label)
 {
 Console.WriteLine("\n" + label);
 foreach(DataTable tbl in ds.Tables)
 {
    Console.WriteLine("TableName: " + tbl.TableName);
    foreach(DataRow row in tbl.Rows)
    {
       foreach(DataColumn col in tbl.Columns)
       {
         Console.Write("dtItems " + row[col] );
       }
       Console.WriteLine();
    }
 }
 Console.ReadLine();
 }
 }
 }
 
//*******************************
// Filling of DataColumn's properties in 4 diferent ways:

using System;
using System.Data;

DataTable dt = new DataTable();

// Add the column to the DataTable to create
DataColumn col1 = dt.Columns.Add();
// Configure the column -- integer with a default = 0 that
// does not allow nulls
col1.ColumnName= "Column-1";
col1.DataType = typeof(int);
col1.DefaultValue = 0;
col1.Unique = true;
col1.AllowDBNull = false;

// Create and configure the column
DataColumn col2 = new DataColumn();
// Configure the column -- string with max length = 50
col2.ColumnName = "Column-2";
col2.DataType = typeof(string);
col2.MaxLength = 50;
// Add the column to the DataTable
dt.Columns.Add(col2);

// Add a column directly using an overload of the Add()
// method of the DataTable.Columns collection -- the column
// is a string with max length = 50
dt.Columns.Add("Column-3", typeof(string)).MaxLength = 50;

// Add multiple existing columns to the DataTable
DataColumn col4 = new DataColumn("Column-4");
// ... configure column 4
DataColumn col5 = new DataColumn("Column-5", typeof(int));
// Add columns 4 and 5 to the DataTable
dt.Columns.AddRange(new DataColumn[] { col4, col5 });

//*******************************
// Adding of DataTable(s) to DataSet in 3 different ways:

DataSet ds = new DataSet();

// Add a DatTable named Table-1 directly
DataTable dt1 = ds.Tables.Add("Table-1");
// ... Configure the DataTable -- add some columns, etc.

// Add a DataTable named Table-2 by creating the table
// and adding it to the DataSet
DataTable dt2 = new DataTable("Table-2");
// ... Configure the DataTable -- add some columns, etc.
ds.Tables.Add(dt2);

// Add multiple DataTables to the DataSet
DataTable dt3 = new DataTable("Table-3");
DataTable dt4 = new DataTable("Table-4");
// ... Configure the DataTable -- add some columns, etc.
ds.Tables.AddRange(new DataTable[] { dt3, dt4 });

//*******************************
// Mapping Table And Column Names:

// Create the connection
string connectString = "Data Source=(local);Integrated security=SSPI;Initial Catalog=AdventureWorks;";

string sqlSelect = "SELECT TOP 5 Title, FirstName, LastName FROM Person.Contact";

SqlDataAdapter da = new SqlDataAdapter(sqlSelect, connectString);

// Create the table mapping to map the default table name 'Table'.
DataTableMapping dtm = da.TableMappings.Add("Table", "mappedContact");

// Create column mappings
dtm.ColumnMappings.Add("Title", "mappedTitle");
dtm.ColumnMappings.Add("FirstName", "mappedFirstName");
dtm.ColumnMappings.Add("LastName", "mappedLastName");

// Create and fill the DataSet
DataSet ds = new DataSet();
da.Fill(ds);

//*******************************
// Mapping Data Types:

string sqlConnectString = "Data Source=(local);Integrated security=SSPI;Initial Catalog=AdventureWorks;";

string sqlSelect = "SELECT TOP 5 ContactID, FirstName, MiddleName, LastName FROM Person.Contact";

int contactID;
string firstName, middleName, lastName;

// Create the connection and the command.
SqlConnection con = new SqlConnection(sqlConnectString);
SqlCommand cmd = new SqlCommand(sqlSelect, con);

// Open the connection and build the DataReader.
con.Open();

using (SqlDataReader dr = cmd.ExecuteReader())
{
    Console.WriteLine("---Cast value retrieved by ordinal---");
    // Get values from the DataReader and cast to int.
    while (dr.Read())
    {
        contactID = Convert.ToInt32(dr[0]);
        firstName = Convert.ToString(dr[1]);
        middleName = Convert.ToString(dr[2]);
        lastName = Convert.ToString(dr[3]);

        Console.WriteLine("{0}\t{1}, {2} {3}",
            contactID, lastName, firstName, middleName);
    }
}

using (SqlDataReader dr = cmd.ExecuteReader())
{
    // Get values from the DataReader using generic typed accessors.
    Console.WriteLine("\n---Generic typed accessors---");
    while (dr.Read())
    {
        contactID = dr.GetInt32(0);
        firstName = dr.GetString(1);
        middleName = dr.IsDBNull(2) ? null : dr.GetString(2);
        lastName = dr.GetString(3);

        Console.WriteLine("{0}\t{1}, {2} {3}",
            contactID, lastName, firstName, middleName);
    }
}

using (SqlDataReader dr = cmd.ExecuteReader())
{
    // Get values from the DataReader using SQL Server
    // specific typed accessors.
    Console.WriteLine("\n---SQL Server specific typed accessors---");
    while (dr.Read())
    {
        contactID = (int)dr.GetSqlInt32(0);
        firstName = (string)dr.GetSqlString(1);
        middleName = dr.IsDBNull(2) ? null :
            (string)dr.GetSqlString(2);
        lastName = (string)dr.GetSqlString(3);

        Console.WriteLine("{0}\t{1}, {2} {3}",
            contactID, lastName, firstName, middleName);
    }
}

//*******************************
// Add calculated DataColumn to DataTable (for info about expr. syntax see DataColumn.Expression property in MSDN):

string sqlConnectString = "Data Source=(local);Integrated security=SSPI;Initial Catalog=AdventureWorks;";
string sqlSelect = "SELECT * FROM Sales.SalesOrderDetail";
SqlDataAdapter da = new SqlDataAdapter(sqlSelect, sqlConnectString);
DataTable dt = new DataTable();
da.Fill(dt);

// Add an expression column to the table.
string expr = "UnitPrice * (1 - UnitPriceDiscount) * OrderQty";
dt.Columns.Add(new DataColumn("ExtendedPrice", typeof(Decimal), expr));

//*******************************
// UniqueConstraint:

DataTable dt = new DataTable("Table-1");
dt.Columns.Add("Id", typeof(int));
dt.Columns.Add("Field1", typeof(string)).MaxLength = 50;
// Create a unique constraint on Field1:
UniqueConstraint uc1 = new UniqueConstraint("UniqueConstraint", dt.Columns["Field1"]);
// Add the constraint to the table:
dt.Constraints.Add(uc1);

// Verify the unique constraint by adding rows:
try
{
    AddRow(dt, 1, "Value 1");
    AddRow(dt, 2, "Value 2");
    AddRow(dt, 3, "Value 2");
}
catch (Exception ex)
{
    Console.WriteLine("Error: {0}", ex.Message);
}

DataView

// В примере демонстрируется взаимодействие автономной таблицы и "заточенного" под нее вьюера.
// Записи в таблицу можно добавлять как непосредственно, так и через вьюер.
// При этом необходимо совершать некоторое количество дополнительных действий. Через вьюер же организуется поиск записей.

using System;
using System.Data;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;

namespace Lights01
{
public class DataViewForm : System.Windows.Forms.Form
{
private System.ComponentModel.Container components = null;

DataTable dataTable;         // Таблица.
DataColumn dataColumn1, dataColumn2;    // Столбцы таблцы.
DataRow dataRow;           // Строка таблицы.
DataView dataView;          // Вьюер таблицы.
DataRowView dataRowView;       // Вьюер строки таблицы.

int currentCounter;   // Счетчик текущей строки для вьюера таблицы.

private System.Windows.Forms.DataGrid dataGrid;
private System.Windows.Forms.DataGrid dataGridForTable;
private System.Windows.Forms.Button buttPrev;
private System.Windows.Forms.Button buttFirst;
private System.Windows.Forms.Button buttLast;
private System.Windows.Forms.Button buttonFind;
private System.Windows.Forms.TextBox demoTextBox;
private System.Windows.Forms.TextBox findTextBox;
private System.Windows.Forms.Button buttonAdd;
private System.Windows.Forms.Button buttonAcc;
private System.Windows.Forms.GroupBox groupBox1;
private System.Windows.Forms.GroupBox groupBox2;
private System.Windows.Forms.Button buttNext;

public DataViewForm()
{
InitializeComponent();
CreateTable();
dataGrid.DataSource = dataView;
dataGridForTable.DataSource = dataTable;
currentCounter = 0;
dataRowView = dataView[currentCounter];
demoTextBox.Text = dataRowView["Item"].ToString();
}

protected override void Dispose( bool disposing )
{
   if( disposing )
   {
      if(components != null)
      {
	      components.Dispose();
      }
   }
   base.Dispose( disposing );
}

#region Windows Form Designer generated code

// Required method for Designer support - do not modify
// the contents of this method with the code editor.

private void InitializeComponent()
{
   this.dataGrid = new System.Windows.Forms.DataGrid();
   this.demoTextBox = new System.Windows.Forms.TextBox();
   this.buttPrev = new System.Windows.Forms.Button();
   this.buttNext = new System.Windows.Forms.Button();
   this.buttFirst = new System.Windows.Forms.Button();
   this.buttLast = new System.Windows.Forms.Button();
   this.findTextBox = new System.Windows.Forms.TextBox();
   this.buttonFind = new System.Windows.Forms.Button();
   this.buttonAdd = new System.Windows.Forms.Button();
   this.dataGridForTable = new System.Windows.Forms.DataGrid();
   this.buttonAcc = new System.Windows.Forms.Button();
   this.groupBox1 = new System.Windows.Forms.GroupBox();
   this.groupBox2 = new System.Windows.Forms.GroupBox();
   ((System.ComponentModel.ISupportInitialize)(this.dataGrid)).BeginInit();
   ((System.ComponentModel.ISupportInitialize)(this.dataGridForTable)).BeginInit();
   this.groupBox1.SuspendLayout();
   this.groupBox2.SuspendLayout();
   this.SuspendLayout();
   // 
   // dG
   // 
   this.dataGrid.DataMember = "";
   this.dataGrid.HeaderForeColor = System.Drawing.SystemColors.ControlText;
   this.dataGrid.Location = new System.Drawing.Point(8, 80);
   this.dataGrid.Name = "dG";


   this.dataGrid.Size = new System.Drawing.Size(280, 128);
   this.dataGrid.TabIndex = 0;
   this.dataGrid.MouseDown += new System.Windows.Forms.MouseEventHandler(this.dG_MouseDown);
   // 
   // demoTextBox
   // 
   this.demoTextBox.Location = new System.Drawing.Point(152, 48);
   this.demoTextBox.Name = "demoTextBox";
   this.demoTextBox.Size = new System.Drawing.Size(128, 20);
   this.demoTextBox.TabIndex = 1;
   this.demoTextBox.Text = "";
   // 
   // buttPrev
   // 
   this.buttPrev.Location = new System.Drawing.Point(189, 16);
   this.buttPrev.Name = "buttPrev";
   this.buttPrev.Size = new System.Drawing.Size(25, 23);
   this.buttPrev.TabIndex = 2;
   this.buttPrev.Text = "<-";
   this.buttPrev.Click += new System.EventHandler(this.buttPrev_Click);
   // 
   // buttNext
   // 
   this.buttNext.Location = new System.Drawing.Point(221, 16);
   this.buttNext.Name = "buttNext";
   this.buttNext.Size = new System.Drawing.Size(25, 23);
   this.buttNext.TabIndex = 3;
   this.buttNext.Text = "->";
   this.buttNext.Click += new System.EventHandler(this.buttNext_Click);
   // 
   // buttFirst
   // 
   this.buttFirst.Location = new System.Drawing.Point(157, 16);
   this.buttFirst.Name = "buttFirst";
   this.buttFirst.Size = new System.Drawing.Size(25, 23);
   this.buttFirst.TabIndex = 4;
   this.buttFirst.Text = "<<";
   this.buttFirst.Click += new System.EventHandler(this.buttFirst_Click);
   // 
   // buttLast
   // 
   this.buttLast.Location = new System.Drawing.Point(253, 16);
   this.buttLast.Name = "buttLast";
   this.buttLast.Size = new System.Drawing.Size(25, 23);
   this.buttLast.TabIndex = 5;
   this.buttLast.Text = ">>";
   this.buttLast.Click += new System.EventHandler(this.buttLast_Click);
   // 
   // findTextBox
   // 
   this.findTextBox.Location = new System.Drawing.Point(8, 48);
   this.findTextBox.Name = "findTextBox";
   this.findTextBox.Size = new System.Drawing.Size(128, 20);
   this.findTextBox.TabIndex = 6;
   this.findTextBox.Text = "";
   // 
   // buttonFind
   // 
   this.buttonFind.Location = new System.Drawing.Point(88, 16);
   this.buttonFind.Name = "buttonFind";
   this.buttonFind.Size = new System.Drawing.Size(48, 23);
   this.buttonFind.TabIndex = 7;
   this.buttonFind.Text = "Find";
   this.buttonFind.Click += new System.EventHandler(this.buttonFind_Click);
   // 
   // buttonAdd
   // 
   this.buttonAdd.Location = new System.Drawing.Point(8, 16);
   this.buttonAdd.Name = "buttonAdd";
   this.buttonAdd.Size = new System.Drawing.Size(40, 23);
   this.buttonAdd.TabIndex = 8;
   this.buttonAdd.Text = "Add";
   this.buttonAdd.Click += new System.EventHandler(this.buttonAdd_Click);
   // 
   // dGforTable
   // 
   this.dataGridForTable.DataMember = "";
   this.dataGridForTable.HeaderForeColor = System.Drawing.SystemColors.ControlText;
   this.dataGridForTable.Location = new System.Drawing.Point(8, 24);
   this.dataGridForTable.Name = "dGforTable";
   this.dataGridForTable.Size = new System.Drawing.Size(272, 120);
   this.dataGridForTable.TabIndex = 9;
   // 
   // buttonAcc
   // 
   this.buttonAcc.Location = new System.Drawing.Point(8, 152);
   this.buttonAcc.Name = "buttonAcc";
   this.buttonAcc.Size = new System.Drawing.Size(40, 23);
   this.buttonAcc.TabIndex = 10;
   this.buttonAcc.Text = "Acc";
   this.buttonAcc.Click += new System.EventHandler(this.buttonAcc_Click);
   // 
   // groupBox1
   // 
   this.groupBox1.Controls.Add(this.buttonAcc);
   this.groupBox1.Controls.Add(this.dataGridForTable);
   this.groupBox1.Location = new System.Drawing.Point(6, 8);
   this.groupBox1.Name = "groupBox1";
   this.groupBox1.Size = new System.Drawing.Size(298, 184);
   this.groupBox1.TabIndex = 11;
   this.groupBox1.TabStop = false;
   this.groupBox1.Text = "Таблица как она есть  ";
   // 
   // groupBox2
   // 
   this.groupBox2.Controls.Add(this.buttPrev);
   this.groupBox2.Controls.Add(this.buttonFind);
   this.groupBox2.Controls.Add(this.buttFirst);
   this.groupBox2.Controls.Add(this.buttLast);
   this.groupBox2.Controls.Add(this.demoTextBox);
   this.groupBox2.Controls.Add(this.buttNext);
   this.groupBox2.Controls.Add(this.dataGrid);
   this.groupBox2.Controls.Add(this.buttonAdd);
   this.groupBox2.Controls.Add(this.findTextBox);
   this.groupBox2.Location = new System.Drawing.Point(8, 200);
   this.groupBox2.Name = "groupBox2";
   this.groupBox2.Size = new System.Drawing.Size(296, 216);
   this.groupBox2.TabIndex = 12;
   this.groupBox2.TabStop = false;
   this.groupBox2.Text = "Вид через вьюер";
   // 
   // DataViewForm
   // 
   this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
   this.ClientSize = new System.Drawing.Size(312, 421);
   this.Controls.Add(this.groupBox2);
   this.Controls.Add(this.groupBox1);
   this.Name = "DataViewForm";
   this.Text = "DataViewForm";
   ((System.ComponentModel.ISupportInitialize)(this.dataGrid)).EndInit();
   ((System.ComponentModel.ISupportInitialize)(this.dataGridForTable)).EndInit();
   this.groupBox1.ResumeLayout(false);
   this.groupBox2.ResumeLayout(false);
   this.ResumeLayout(false);
}
#endregion

private void CreateTable()
{
   // Создается таблица. 
   dataTable = new DataTable("Items");

   // Столбцы таблицы...
   // Имя первого столбца - id, тип значения - System.Int32.
   dataColumn1 = new DataColumn("id", Type.GetType("System.Int32"));
   dataColumn1.AutoIncrement = true;
   // Имя второго столбца - Item, тип значения - System.Int32.
   dataColumn2 = new DataColumn("Item", Type.GetType("System.Int32"));

   // К таблице добавляются объекты-столбцы...   
   dataTable.Columns.Add(dataColumn1);
   dataTable.Columns.Add(dataColumn2);

   // А вот массив столбцов (здесь он из одного элемента)
   // для организации первичного ключа (множества первичных ключей).
   DataColumn[] keyColumns = new DataColumn[1];
   // И вот, собственно, как в таблице задается множество первичных ключей.
   keyColumns[0] = dataColumn1;
   // Свойству объекта t передается массив, содержащий столбцы, которые
   // формируемая таблица t будет воспринимать как первичные ключи.
   dataTable.PrimaryKey = keyColumns;

   // В таблицу добавляется 10 rows.
   for(int i = 0; i <10;i++)
   {
      dataRow=dataTable.NewRow();
      dataRow["Item"]= i;
      dataTable.Rows.Add(dataRow);
   }

   // Принять изменения.
   // Так производится обновление таблицы.
   // Сведения о новых изменениях и добавлениях будут фиксироваться
   // вплоть до нового обновления.
   dataTable.AcceptChanges();	

   // Здесь мы применим специализированный конструктор, который 
   // задаст значения свойств Table, RowFilter, Sort, RowStateFilter
   // объекта DataView в двух операторах кода...
   //dv = new DataView(dt); // Вместо этого...
   // Определение того, что доступно через объект - представитель DataView.
   // Задавать можно в виде битовой суммы значений. И не все значения сразу!
   // Сумма всех значений - противоречивое сочетание!
   // А можно ли делать это по отдельности?
   DataViewRowState dvrs = DataViewRowState.Added |
			   DataViewRowState.CurrentRows |
			   DataViewRowState.Deleted |
			   DataViewRowState.ModifiedCurrent |

			   //DataViewRowState.ModifiedOriginal |
			   //DataViewRowState.OriginalRows |
			   //DataViewRowState.None |
   // Записи не отображаются.
   DataViewRowState.Unchanged;
   // Вот такое хитрое объявление...
   //  	Таблица,
   //  	|	значение, относительно которого проводится сортировка,
   //  	|   |  
   //  	|   | имя столбца, значения которого сортируются,
   //  	|   |   |                           
   //  	|   |   |  составленное значение DataViewRowState.
   //  	|   |   |      |
   dataView = new DataView(dataTable, "", "Item", dvrs);
}

private void buttNext_Click(object sender, System.EventArgs e)
{
   if (currentCounter+1 < dataView.Count) currentCounter++;
   dataRowView = dataView[currentCounter];
   demoTextBox.Text = dataRowView["Item"].ToString();
}


private void buttPrev_Click(object sender, System.EventArgs e)
{
   if (currentCounter - 1 >= 0) currentCounter--;
   dataRowView = dataView[currentCounter];
   demoTextBox.Text = dataRowView["Item"].ToString();
}

private void buttFirst_Click(object sender, System.EventArgs e)
{
   currentCounter = 0;
   dataRowView = dataView[currentCounter];
   demoTextBox.Text = dataRowView["Item"].ToString();
}

private void buttLast_Click(object sender, System.EventArgs e)
{
   currentCounter = dataView.Count - 1;
   dataRowView = dataView[currentCounter];
   demoTextBox.Text = dataRowView["Item"].ToString();
}

private void dG_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
{
   currentCounter = dataGrid.CurrentRowIndex;
   dataRowView = dataView[currentCounter];
   demoTextBox.Text = dataRowView["Item"].ToString();
}

// Реализация поиска требует специального опеделения порядка 
// сортировки строк, который должен задаваться в конструкторе.
private void buttonFind_Click(object sender, System.EventArgs e)
{
   int findIndex = -1;

   // Сначала проверяем строку на соответствие формату отыскиваемого 
   // значения.
   // В нашем случае строка должна преобразовываться в целочисленное 
   // значение.
   try
   {
      int.Parse(findTextBox.Text);	
   }
   catch
   {
      findTextBox.Text = "Неправильно задан номер...";
      return;
   }

   findIndex = dataView.Find(findTextBox.Text);

   if (findIndex >= 0) 
   {
      currentCounter = findIndex;
      dataRowView = dataView[currentCounter];
      demoTextBox.Text = dataRowView["Item"].ToString();
   }
   else
   {
      findTextBox.Text = "Не нашли.";
   }
}

private void buttonAdd_Click(object sender, System.EventArgs e)
{
   // При создании новой записи средствами вьюера таблицы,
   // связанный с ним вьюер строки переходит в состояние rv.IsNew.
   // При этом в действиях этих объектов есть своя логика.
   // И если туда не вмешиваться, при создании очередной записи
   // предыдущая запись считается принятой и включается в таблицу 
   // автоматически.
   // Контролируя состояния вьюера строки (rv.IsEdit || rv.IsNew),
   // мы можем предотвратить процесс последовательного автоматического
   // обновления таблицы. Все под контролем.
   if (dataRowView.IsEdit || dataRowView.IsNew) return;
   dataRowView = dataView.AddNew();
   dataRowView["Item"] = dataView.Count - 1;
}

private void buttonAcc_Click(object sender, System.EventArgs e)
{
   // И вот мы вмешались в процесс.
   // Добавление новой записи в таблицу становится возможным лишь
   // после явного завершения редактирования предыдущей записи.
   // Без этого попытки создания новой записи блокируются.
   // Завершить редактирование.
   dataRowView.EndEdit(); 
   // Принять изменения.
   // Так производится обновление таблицы.
   // Сведения о новых изменениях и добавлениях будут фиксироваться
   // вплоть до нового обновления.
   dataTable.AcceptChanges();	
}
} // public class DataViewForm : System.Windows.Forms.Form
} // namespace Lights01

DataReader

int					idx;
string					customerName;
System.Data.SqlClient.SqlCommand	mySqlCommand;
System.Data.SqlClient.SqlDataReader	mySqlDataReader;

MyConnection.Open();
mySqlDataReader = mySqlCommand.ExecuteReader();

// У объекта DataReader имеется "указатель чтения", который устанавливается на первую запись результирующего набора записей,
// образовавшегося в результате выполнения метода ExecuteReader(). Очередная (в том числе и первая) запись набора становится
// доступной в результате выполнения метода Read(). В случае успешного выполнения этого метода указатель переводится на следующий
// элемент результирующей записи, а метод Read() возвращает значение true. В противном случае метод возвращает значение false.

while (myDataReader.Read())
{
	// DataReader returns object type...
	object myObj0 = myDataReader[5]; // access column by index
	object myObj1 = myDataReader["CustomerID"]; // access column by name

	// ...but it's possible to get typed result (using GetString, GetInt32, GetBoolean etc.):
	idx = myDataReader.GetOrdinal("CustomerName"); // Определить порядковый номер поля 'CustomerName'
	customerName = myDataReader.GetString(idx); // Извлечь строку из этого поля и прописать ее в переменную
}

myReader.Close();
MyConnection.Close();
-----------------------------------------------------------------------------------------------------------------------------------------
using System;
using System.Data.SqlClient;

namespace ConsoleApplication1
{
class Report
{
   static void Main(string[] args)
   {
      int            orderId;
      DateTime       orderDate;
      DateTime       shipDate;
      string         shipName;
      string         shipAddress;
      string         shipCity;
      string         shipCountry;
      string         customerId;
      SqlConnection  theSqlConnection = new SqlConnection();
      SqlCommand     theSqlCommand = new SqlCommand();
      SqlDataReader  theSqlDataReader = null;

      try
      {
         // Initialize:
         theSqlConnection.ConnectionString =
            "Integrated Security=true;Initial Catalog=Northwind;Data Source=ACER-684C9A655D\\SQLEXPRESS";
         theSqlConnection.Open();
         theSqlCommand.Connection = theSqlConnection;

         // Create SELECT statement:
         Console.Write("Pleas enter a customer ID (5 characters): ");
         customerId = Console.ReadLine();
         theSqlCommand.CommandText =
               "SELECT OrderID, OrderDate, ShippedDate, ShipName, ShipAddress, ShipCity, ShipCountry " +
               "  FROM Orders " +
               " WHERE CustomerID = '" + customerId + "'";
         Console.WriteLine("About to execute: {0}\n\n", theSqlCommand.CommandText);

         // Retrieve:
         theSqlDataReader = theSqlCommand.ExecuteReader();

         // Display retrieved data:
         while (theSqlDataReader.Read())
         {
            orderId = theSqlDataReader.GetInt32(0);
            if (theSqlDataReader.IsDBNull(2))
            {
               Console.WriteLine("Order: {0} not yet shipped", orderId);
               continue;
            }
            orderDate = theSqlDataReader.GetDateTime(1);
            shipDate = theSqlDataReader.GetDateTime(2);
            shipName = theSqlDataReader.GetString(3);
            shipAddress = theSqlDataReader.GetString(4);
            shipCity = theSqlDataReader.GetString(5);
            shipCountry = theSqlDataReader.GetString(6);
            Console.WriteLine("Order: {0}\nPlaced: {1}\nShipped: {2}\nToAddress: {3}\n{4}\n{5}\n{6}\n",
               orderId, orderDate, shipDate, shipName, shipAddress, shipCity, shipCountry);
         }
         theSqlDataReader.Close();
      }
      catch (SqlException e)
      {

         Console.WriteLine("DB error: {0}", e.Message);
         Console.ReadLine();
      }
      finally
      {
         theSqlConnection.Close();
      }
   }
} // class Report
} // namespace ConsoleApplication1

Web Controls
// Access field in GridView by name:

using System;
using System.Web.UI.WebControls;

public partial class _Default : System.Web.UI.Page 
{
    
    protected void SqlDataSource1_Updating(object sender, SqlDataSourceCommandEventArgs e)
    {
        string companyName;

        companyName = ((TextBox)CustomerGridView.SelectedRow.FindControl("CompanyName")).Text;
    }
}
-----------------------------------------------------------------------------------------------------------------------
// Open page from other page passing parameter.
// Page CustomerData.aspx opens page OrderHistory.aspx passing CustomerID as parameter.
// The link is field CustomerID in GridView on CustomerData.aspx (click on it opens orders history for that customer).

//****** CustomerData.aspx:

// Convert fild in calling GridView to link (from BoundField to HyperLinkField):
<asp:HyperLinkField DataTextField="CustomerID" HeaderText="CustomerID" SortExpression="CustomerID"
     target="_blank" DataNavigateUrlFields="CustomerID" DataNavigateUrlFormatString="~\OrderHistory.aspx?CustomerID={0}" />

//****** OrderHistory.aspx.cs:

using System;
using System.Web.UI.WebControls;

public partial class OrderHistory : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        // Extract argument from request:
        string customerId = Request.QueryString["CustomerID"];

        // Cosmetics:
        this.OrderLabel.Text += " " + customerId;
        this.Title += " " + customerId;

        // Set DataSource of OrderGridView to stored proc CustOrderHist():
        OrderHistoryDataContext context = new OrderHistoryDataContext();
        var orderDetails = context.CustOrderHist(customerId); // method name - as stored proc name
        this.OrderGridView.DataSource = orderDetails;

        // Bind two columns in OrderGridView to corresponding properties in data source:
        BoundField productName = this.OrderGridView.Columns[0] as BoundField;
        BoundField total = this.OrderGridView.Columns[1] as BoundField;
        productName.DataField = "ProductName";
        total.DataField = "Total";
        this.OrderGridView.DataBind();
    }
}

Web Service

// WebService (http://msdn.microsoft.com/ru-ru/library/s5xy331f.aspx):

<% @ WebService Language = "C#" Class = "Sample" %>
using System;
using System.Data;
using System.Data.SqlClient;
using System.Web.Services;

[WebService(Namespace="http://microsoft.com/webservices/")]
public class Sample
{
  public SqlConnection _cn = new SqlConnection("Data Source=(local);Integrated Security=SSPI;Initial Catalog=Northwind");

  [WebMethod( Description = "Returns Northwind Customers", EnableSession = false )]
  public DataSet GetCustomers()
  {
    string         sql;
    SqlDataAdapter daCustomers;
    DataSet        dsCustomers;

    sql = "SELECT CustomerID, CompanyName FROM Customers";
    daCustomers = new SqlDataAdapter(sql, _cn);
    dsCustomers = new DataSet();

    daCustomers.MissingSchemaAction = MissingSchemaAction.AddWithKey;
    daCustomers.Fill(dsCustomers, "Customers");
 
    return dsCustomers;
  } // end of GetCustomers()

  [WebMethod( Description = "Updates Northwind Customers", EnableSession = false )]
  public DataSet UpdateCustomers(DataSet adsCustomers)
  {
    string         sql;
    SqlDataAdapter daCustomers = new SqlDataAdapter();

    sql = "INSERT INTO Customers (CustomerID, CompanyName) VALUES (@CustomerID, @CompanyName)";
    daCustomers.InsertCommand = new SqlCommand(sql, _cn);
    daCustomers.InsertCommand.Parameters.Add("@CustomerID", SqlDbType.NChar, 5, "CustomerID");
    daCustomers.InsertCommand.Parameters.Add("@CompanyName", SqlDbType.NChar, 15, "CompanyName");

    sql = "UPDATE Customers Set CustomerID = @CustomerID, CompanyName = @CompanyName WHERE CustomerID = @OldCustomerID";
    daCustomers.UpdateCommand = new SqlCommand(sql, _cn);
    daCustomers.UpdateCommand.Parameters.Add("@CustomerID", SqlDbType.NChar, 5, "CustomerID");
    daCustomers.UpdateCommand.Parameters.Add("@CompanyName", SqlDbType.NChar, 15, "CompanyName");
    SqlParameter parameter = daCustomers.UpdateCommand.Parameters.Add("@OldCustomerID", SqlDbType.NChar, 5, "CustomerID");
    parameter.SourceVersion = DataRowVersion.Original;

    sql = "DELETE FROM Customers WHERE CustomerID = @CustomerID";
    daCustomers.DeleteCommand = new SqlCommand(sql, _cn);
    parameter = daCustomers.DeleteCommand.Parameters.Add("@CustomerID", SqlDbType.NChar, 5, "CustomerID");
    parameter.SourceVersion = DataRowVersion.Original;

    daCustomers.Update(adsCustomers, "Customers");

    return adsCustomers;
  } // end of UpdateCustomers(DataSet adsCustomers)
}

Transaction

SqlConnection  conn;
SqlCommand     command1;
SqlCommand     command2;
Transaction    tran;

try
{
   conn.Open();
   
   // Create Transaction object:
   tran = conn.BeginTransaction();

   // Use the transaction object in commands:
   command1.Transaction = tran;
   command2.Transaction = tran;

   // Execute commands:
   command1.ExecuteNonQuery();
   command2.ExecuteNonQuery();
   
   tran.Commit();  
}   
catch
{
   tran.Rollback();  
}
finally
{
   conn.Close();
}

Tips of any kind

throw new ArgumentOutOfRangeException("Bad argument");

DataRowVersion enum: Current, Default, Original, Proposed
DataRowState: Added, Deleted, Detached, Modified, Unchanged