Российский Государственный Технологический Университет им. К.Э. Циолковского
Опубликован: 02.03.2007 | Доступ: свободный | Студентов: 5678 / 802 | Оценка: 3.96 / 3.45 | Длительность: 27:04:00
ISBN: 978-5-9556-0086-4
Лекция 18:

Основы ADO .NET

< Лекция 17 || Лекция 18: 123456789101112

ADO .NET. Доступ к данным

Предполагается, что к моменту написания приложения соответствующая база данных уже создана.

Объектная модель ADO .NET реализует отсоединенный доступ к данным. При этом в Visual Studio .NET существует множество ВСТРОЕННЫХ мастеров и дизайнеров, которые позволяют реализовать механизмы доступа к БД еще на этапе разработки программного кода.

С другой стороны, задача получения доступа к данным может быть решена непосредственно во время выполнения приложения.

Концепция доступа к данным в ADO .NET основана на использовании двух компонентов:

  • НАБОРА ДАННЫХ (представляется объектом класса DataSet ) со стороны клиента. Это локальное временное хранилище данных;
  • ПРОВАЙДЕРА ДАННЫХ (представляется объектом класса DataProvider ). Это посредник, обеспечивающий взаимодействие приложения и базы данных со стороны базы данных (в распределенных приложениях – со стороны сервера).

ADO .NET. Объектная модель

Объектная модель ADO .NET предполагает существование (при написании приложения для работы с базой данных — использование) двух множеств классов, выполняющих четко определенные задачи при работе с базой данных:


Классы подсоединенных объектов обеспечивают установление соединения с базой данных и управление базой со стороны приложения; классы отсоединенных объектов обеспечивают сохранение, использование и преобразование полученной от базы данных информации на стороне приложения.

Далее рассматриваются классы отсоединенных объектов объектной модели ADO .NET. Их подробному описанию посвящаются следующие разделы пособия. При этом классы отсоединенных объектов могут быть самостоятельно использованы в приложении наряду с обычными компонентами и элементами управления, даже если в приложении и не предполагается организовывать работу с базами данных.

DataTable

Каждый объект DataTable представляет одну таблицу базы данных. Таблица в каждый конкретный момент своего существования характеризуется:

  • СХЕМОЙ таблицы,
  • СОДЕРЖИМЫМ таблицы (информацией).

При этом СХЕМА таблицы (структура объекта DataTable ) определяется двумя наборами:

  • множеством столбцов таблицы (набор DataColumns, состоящий из множества объектов DataColumn ),
  • множеством ограничений таблицы (набор Constraints, состоящий из множества объектов Constraint ).

События класса DataTable

В классе определены четыре события, которые позволяют перехватывать и в случае необходимости отменять изменения состояния таблицы данных.

  1. Изменения строк.
    • DataRowChanging – изменения вносятся в строку таблицы.

      Объявление соответствующего обработчика события имеет вид

      private static void Row_Changing( object sender, DataRowChangeEventArgs e )
    • DataRowChanged – изменения внесены в строку таблицы.

      Объявление соответствующего обработчика события имеет вид

      private static void Row_Changed( object sender, DataRowChangeEventArgs e )

    Пример программного кода для объекта – представителя класса DataTable:

    using System;
     using System.Data;
    
     namespace DataRowsApplication00
     {
     class DataTester
     {
     DataTable custTable;
    
     public void DTBuild()
     {
     custTable = new DataTable("Customers");
     // Добавляем столбики.
     custTable.Columns.Add("id", typeof(int));
     custTable.Columns.Add("name", typeof(string));
    
     // Определяем первичный ключ.
     custTable.Columns["id"].Unique = true;
     custTable.PrimaryKey = new DataColumn[] { custTable.Columns["id"] };
    
     // Добавляем RowChanging event handler для нашей таблицы.
     custTable.RowChanging += new DataRowChangeEventHandler(Row_Changing);
     // Добавляем a RowChanged event handler для нашей таблицы.
     custTable.RowChanged += new DataRowChangeEventHandler(Row_Changed);
     }
    
     public void RowsAdd(int id)
     {
     int x;
     // Добавляем строки.
     for (x = 0; x < id; x++)
     {
         custTable.Rows.Add(new object[] { x, string.Format("customer{0}", x) });
     }
     // Фиксируются все изменения, которые были произведены над таблицей
     // со времени последнего вызова AcceptChanges. 
     custTable.AcceptChanges();
     }
    
     public void RowsChange()
     {
     // Изменяем значение поля name во всех строках.
     // Все имена убираются, а на их место
     // подставляется буквосочетание, состоящее из
     // префикса vip и старого значения строки каждого клиента.
     // Была строка customer5 – стала vip customer5.
    
     foreach (DataRow row in custTable.Rows)
     {
         row["name"] = string.Format("vip {0}", row["id"]);
     }
    
     }
    
     // И после вмешательства результаты становятся известны
     // обработчику события Row_Changing. А толку-то...
     private static void Row_Changing(object sender, DataRowChangeEventArgs e)
     {
     Console.WriteLine("Row_Changing Event: name={0}; action={1}",
                                                 e.Row["name"],
                                                 e.Action);
     }
    
     // Аналогично устроен обработчик Row_Changed.
     private static void Row_Changed(object sender, DataRowChangeEventArgs e)
     {
     Console.WriteLine("Row_Changed Event: name={0}; action={1}",
                                               e.Row["name"],
                                                  e.Action);
     }    
     }
     class Program
     {
      static void Main(string[] args)
      {
       DataTester dt = new DataTester();
        dt.DTBuild();
        dt.RowsAdd(10);
        dt.RowsChange();
       }
      }
     }
    Листинг 18.1.

    Параметр обработчика события DataRowChangeEventArgs обладает двумя свойствами ( Action и Row ), которые позволяют определить изменяемую строку и выполняемое над строкой действие. Действие кодируется значениями специального перечисления:

    enum RowDataAction
     {
      Add,
      Change,
      Delete,
      Commit,
      Rollback,
      Nothing
     }
  2. Изменения полей (элементов в строках таблицы)
    • DataColumnChanging – изменения вносятся в поле строки данных.

      Объявление соответствующего обработчика события имеет вид

      private static void Column_Changing
                          (object sender, DataColumnChangeEventArgs e)
    • DataColumnChanged – изменения были внесены в поле строки данных.

      Объявление соответствующего обработчика события имеет вид

      private static void Column_Changed
                         (object sender, DataColumnChangeEventArgs e)

    Параметр обработчика события DataColumnChangeEventArgs e обладает тремя свойствами:

    Свойство Описание
    Column Get. Объект-представитель класса DataColumn с изменённым значением
    ProposedValue Gets, sets. Новое значение для поля в строке
    Row Строка, содержащая запись с изменяемым (измененным) значением

    Аналогичный пример. Только теперь программируется реакция на модификацию столбца (поля), а не строки:

    using System;
     using System.Data;
    
     namespace DataColumnsApplication00
     {
     class DataTester
     {
     DataTable custTable;
    
     public void DTBuild()
     {
     custTable = new DataTable("Customers");
     // Добавляем столбики.
     custTable.Columns.Add("id", typeof(int));
     custTable.Columns.Add("name", typeof(string));
    
     // Определяем первичный ключ.
     custTable.Columns["id"].Unique = true;
     custTable.PrimaryKey = new DataColumn[] { custTable.Columns["id"] };
    
     // Добавление события ColumnChanging handler для таблицы.
     custTable.ColumnChanging +=
                  new DataColumnChangeEventHandler(Column_Changing);
     // Добавление события ColumnChanged event handler для таблицы. 
     custTable.ColumnChanged +=
                 new DataColumnChangeEventHandler(Column_Changed);
     }
    
     public void RowsAdd(int id)
     {
     int x;
     // Добавляем строки.
     for (x = 0; x < id; x++)
     {
         custTable.Rows.Add(new object[] { x, string.Format("customer{0}", x) });
     }
     // Фиксируются все изменения, которые были произведены над таблицей
     // со времени последнего вызова AcceptChanges. 
     custTable.AcceptChanges();
     }
    
     public void RowsChange()
     {
     // Изменяем значение поля name во всех строках.
     foreach (DataRow row in custTable.Rows)
     {
         row["name"] = string.Format("vip{0}", row["id"]);
     }
     }
    
     // И после вмешательства результаты становятся известны
     // обработчику события Column_Changing. А толку-то...
     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);
     }
    
     // Аналогично устроен обработчик Column_Changed.
         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);
     }    
     }
     class Program
     {
      static void Main(string[] args)
      {
       DataTester dt = new DataTester();
        dt.DTBuild();
        dt.RowsAdd(10);
        dt.RowsChange();
       }
      }
     }
    Листинг 18.2.
< Лекция 17 || Лекция 18: 123456789101112
kewezok kewezok
kewezok kewezok
Елена Шляхт
Елена Шляхт
Объясните плиз в чем отличие а++ от ++а
Почему результат разный?
int a=0, b=0;
Console.WriteLine(a++); //0
Console.WriteLine(++b); //1
a++;
++b;
Console.WriteLine(a); //2
Console.WriteLine(b); //2