Вы находитесь на странице: 1из 9

1

Доступ к отсоединенным данным


В приложениях, работающих с базами данных, может применяться
доступ к данным через постоянное соединение с источником данных.
Приложение открывает соединение с базой данных и не закрывает его по
крайней мере до завершения работы с источником данных. В это время
соединение с источником поддерживалось постоянно.
Недостатки такого подхода стали выявляться после появления
приложений, ориентированных на Интернет.
Соединения с базой данных требуют выделения системных ресурсов, и
если база данных располагается на сервере, то при большом количестве
клиентов это может быть критично для сервера. Хотя постоянное соединение
и позволяет немного ускорить работу приложения, общий убыток от
растраты системных ресурсов преимущество в скорости выполнения
приложения сводит на нет.
В ADO.NET используется другая модель доступа – доступ к
отсоединенным данным. При этом соединение устанавливается лишь на то
время, которое необходимо для проведения определенной операции над
базой данных.
ADO.NET (ActiveX Data Objects .NET) является набором классов,
реализующих программные интерфейсы для облегчения подключения к
базам данных из приложения независимо от особенностей реализации
конкретной системы управления базами данных и от структуры самой базы
данных, а также независимо от места расположения этой самой базы — в
частности, в распределенной среде (клиент-серверное приложение) на
стороне сервера.

Предполагается, что к моменту написания приложения


соответствующая база данных уже создана.

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


двух компонентов:

 НАБОРА ДАННЫХ (представляется объектом класса DataSet)


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

DataSet
В рамках отсоединенной модели ADO .NET объект DataSet становится
важным элементом технологии отсоединенного доступа. Объект-
представитель DataSet ПРЕДСТАВЛЯЕТ МНОЖЕСТВО ТАБЛИЦ.
Для успешного решения задачи представления в DataSet'е есть все
необходимое. Его функциональные возможности позволяют загрузить в
локальное хранилище на стороне приложения данные из любого
допустимого для ADO .NET источника: SQL Server, Microsoft Access, XML-
файл.
Объект DataSet может представлять абсолютно точную модель базы
данных, и в таком случае эта модель должна будет включать полный набор
структурных элементов базы данных, включая таблицы, содержащие данные,
с учетом установленных ограничений и отношений между таблицами.
Содержащуюся в объекте DataSet информацию можно изменять
независимо от источника данных (от самой БД). Соответствующие значения
формируются непосредственно в программе и добавляются в таблицы.
При работе с базой данных данные могут собираться из разных таблиц,
локальное представление которых обеспечивается различными объектами –
представителями классов DataSet. В классе DataSet определено множество
перегруженных методов Merge, которые позволяют объединять содержимое
нескольких объектов DataSet.
Любой объект-представитель класса DataSet позволяет организовать
чтение и запись содержимого (теоретически – информации из базы) в файл
или область памяти. При этом можно читать и сохранять:

 только содержимое объекта (собственно информацию из базы);


 только структуру объекта – представителя класса DataSet;
 полный образ DataSet (содержимое и структуру).

Таким образом, DataSet является основой для построения различных


вариантов отсоединенных объектов – хранилищ информации.

Класс DataSet – класс не абстрактный и не интерфейс. Это значит, что


существует множество вариантов построения отсоединенных хранилищ.

На основе базового класса DataSet можно определять производные


классы определенной конфигурации, которая соответствует структуре базы
данных.

Можно также создать объект – представитель класса DataSet


оригинальной конфигурации и добавить непосредственно к этому объекту
все необходимые составляющие в виде таблиц (объектов – представителей
класса Table) соответствующей структуры и множества отношений Relation.
3

Объект – представитель класса DataSet и сам по себе, без


сопутствующего окружения, представляет определенную ценность. Дело в
том, что информация, представляемая в приложении в виде таблиц, НЕ
ОБЯЗЯТЕЛЬНО должна иметь внешний источник в виде реальной базы
данных. Ничто не мешает программисту обеспечить в приложении чтение
обычного "плоского" файла или даже "накопить" необходимую информацию
посредством интерактивного взаимодействия с пользователем, используя при
этом обычный диалог. В конце концов, база данных – это один из возможных
способов ОРГАНИЗАЦИИ информации (а не только ее хранения!). Не
случайно DataSet представляет ОТСОЕДИНЕННЫЕ данные.

В свою очередь, в приложении, обеспечивающем взаимодействие с


базой данных, объект DataSet функционирует исключительно за счет
объекта DataAdapter, который обслуживает DataSet.

При этом DataAdapter является центральным компонентом


архитектуры отсоединенного доступа.

Подсоединенные объекты модели ADO .NET. Провайдеры

Поставщик данных для приложения (Провайдер) – объект,


предназначенный для обеспечения взаимодействия приложения с
хранилищем информации (базами данных).

Естественно, приложению нет никакого дела до того, где хранится и


как извлекается потребляемая приложением информация. Для приложения
источником данных является тот, кто передает данные приложению. И как
сам этот источник эту информацию добывает – никого не касается.

Источник данных (Data Provider) – это набор взаимосвязанных


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

ADO .NET поддерживает два типа источников данных, соответственно,


два множества классов:

 SQL Managed Provider (SQL Server.NET Data Provider) – для работы с


Microsoft SQL Server 7.0 и выше. Работает по специальному протоколу,
называемому TabularData Stream (TDS) и не использует ни ADO, ни
ODBC, ни какую-либо еще технологию. Ориентированный специально
на MS SQL Server, протокол позволяет увеличить скорость передачи
данных и тем самым повысить общую производительность
приложения;
4

 ADO Managed Provider (OleDb.NET Data Provider) – для всех


остальных баз данных. Обеспечивает работу с произвольными базами
данных. Однако за счет универсальност и есть проигрыш по сравнению
с SQL Server Provider, так что при работе с SQL Server рекомендовано
использовать специализированные классы.

В следующих разделах приводится описание составных элементов


провайдера.

Connection
Объект – представитель класса Connection представляет соединение с
источником (базой) данных и обеспечивает подключение к базе данных.
Visual Studio .NET поддерживает два класса:

 SQLConnection (обеспечивает подключение к SQL Server 7.0 и


выше),
 OleDbConnection (обеспечивает подключение к прочим
вариантам БД).

Компонента Connection (независимо от того, представителем какого


класса она является) имеет свойство ConnectionString, в котором
фиксируется вся необходимая для установления соединения с БД
информация. Кроме того, поддерживается ряд методов, позволяющих
обрабатывать данные с применением транзакций.

Свойства объекта Connection позволяют:

 задавать реквизиты пользователя;


 указывать расположение источника данных.

Методы объекта позволяют управлять соединением с источником


данных.

Формирование строки и последовательность действий при


инициализации объекта соединения – дело техники. Главное – это чтобы
свойство ConnectionString в результате получило бы ссылку на строку
символов, содержащую необходимую для установления соединения
информацию.
5

Свойства
ConnectionString string Строка, определяющая способ
подключения объекта к источнику
данных
ConnectionTimeout Int32 Интервал времени, в течение
которого объект пытается установить
соединение с источником данных
(только для чтения)
DataSource string Get. Имя сервера или имя файла-
источника данных. Все зависит от того,
с каким хранилищем информации
ведется работа. Серверное хранилище
данных (SQL Server, Oracle) – имя
компьютера, выступающего в роли
сервера. Файловые БД (Access) – имя
файла
Provider string имя OLE DB провайдера, которое
было объявлено в "Provider= ..." строки
соединения
ServerVersion string Get. Строка с информацией о
версии сервера, с которым было
установлено соединение
State string Gets текущее состояние
соединения

Текущее состояние соединения кодируется как элемент перечисления


ConnestionState. Список возможных значений представлен ниже.

Имя
Описание Value
члена
Broken Соединение с источником данных 16
разорвано. Подобное может случиться
только после того, как соединение было
установлено. В этом случае соединение
может быть либо закрыто, либо повторно
открыто
Closed Соединение закрыто 0
Connecting Идет процесс подключения (значение 2
зарезервировано)
6

Executing Соединение находится в процессе 4


выполнения команды (значение
зарезервировано.)
Fetching Объект соединения занят выборкой 8
данных (значение зарезервировано)
Open Соединение открыто 1
Открытые методы
Close Закрывает подключение к источнику данных. Это
рекомендуемый метод закрытия любого открытого
подключения
Open Открывает подключение к базе данных со значениями
свойств, определяемыми ConnectionString
События
Disposed Это событие сопровождает процесс удаления
объекта
InfoMessage Некоторые СУБД (SQL Server) поддерживают
механизм информационных сообщений. Это событие
происходит при отправке провайдером некоторых
сообщений
StateChange Возникает при изменении состояния соединения
Подключение к БД на этапе разработки приложения
Ближайшей задачей будет разработка простого Windows-приложения,
обеспечивающего просмотр содержащейся в базе информации о работниках
и их отделах.

Внешний вид формы приложения будет представлен несколькими


текстовыми полями, в которых будет отображаться информация об отделе, а
также элементом DataGrid, где будет отображаться информация о связанном
с отделом работниках.
Итак, мы создали базу данных и таблицы, которые будут выполнять
функции по хранению данных. И теперь мы можем использовать
инфраструктуру ADO.NET для подключения к ним.
После определения источника данных мы можем к нему
подключаться.
Первым делом нам надо определить строку подключения,
предоставляющая информацию о базе данных и сервере, к которым
предстоит установить подключение:
string connectionString = "Data Source=.\SQLEXPRESS;Initial
Catalog=usersdb;Integrated Security=True";
7

При использовании различных систем управления базами данных,


различных провайдеров данных строка подключения может отличаться.
Строка подключения представляет набор параметров в виде пар
ключ=значение. В данном случае для подключения к ранее созданной базе
данных usersdb мы определяем строку подключения из трех параметров:
Data Source: указывает на название сервера. По умолчанию это
".\SQLEXPRESS". Поскольку в строке используется слеш, то в начале
строки ставится символ @. Если имя сервера базы данных отличается, то
соответственно его и надо использовать.
Initial Catalog: указывает на название базы данных на сервере
Integrated Security: устанавливает проверку подлинности. По
умолчанию значение false.
Атрибут providerName задает пространство имен провайдера
данных. Так как мы будем подключаться к базе данных MS SQL Server, то
соответственно мы будем использовать провайдер для SQL Server,
функциональность которого заключена в пространстве имен
System.Data.SqlClient.
Параметры строки подключения
Application Name: название приложения. Может принимать в
качестве значения любую строку.
AttachDBFileName: хранит полный путь к прикрепляемой базе
данных
Connect Timeout: временной период в секундах, через который
ожидается установка подключения. Принимает одно из значений из
интервала 0–32767. По умолчанию равно 15.
Data Source: название экземпляра SQL Servera, с которым будет
идти взаимодействие. Это может быть название локального сервера,
например, "EUGENEPC/SQLEXPRESS", либо сетевой адрес.
Encrypt: устанавливает шифрование SSL при подключении. По
умолчанию значение false
Initial Catalog: хранит имя базы данных
В качестве альтернативного названия параметра можно
использовать Database
Packet Size: размер сетевого пакета в байтах. Может принимать
значение, которое кратно 512. По умолчанию равно 8192
Persist Security Info: указывает, должна ли конфиденциальная
информация передаваться обратно при подключении. Может принимать
значения true, false, yes и no. По умолчанию значение false
Workstation ID: указывает на рабочую станцию - имя локального
компьютера, на котором запущен SQL Server
Password: пароль пользователя

User ID: логин пользователя


8

Например, если для подключения необходим логин и пароль, то мы


можем их передать в строку подключения через параметры user id и
password:
string connectionString = @"Data Source=.\SQLEXPRESS;Initial
Catalog=usersdb;User Id = sa; Password = 1234567fd";";

DataSet представляет хранилище данных, с которыми можно


работать независимо от наличия подключения, а SqlDataAdapter
заполняет DataSet данными из БД.
Для получения данных через объект SqlDataAdapter необходимо
организовать подключение к БД и выполнить команду SELECT. Есть
несколько способов создания SqlDataAdapter:
SqlDataAdapter adapter = new SqlDataAdapter();
SqlDataAdapter adapter = new SqlDataAdapter(command);
SqlDataAdapter adapter = new SqlDataAdapter(sql, connection);
SqlDataAdapter adapter = new SqlDataAdapter(sql, connectionString);

- Можно использовать конструктор без параметров, а команду


SELECT и подключение установить позже;
- Можно передать в конструктор объект SqlCommand;
- Можно в конструкторе установить sql-выражение SELECT и объект
SqlConnection;
- Можно в конструкторе установить sql-выражение SELECT и строку
подключения.

Рассмотрим, как получить данные в DataSet через SqlDataAdapter.


using System;
using System.Data;
using System.Windows.Forms;
using System.Data.SqlClient;

namespace WindowsFormsApp2
{
public partial class Form1 : Form
{
string connectionString = "Data
Source=(LocalDB)\\MSSQLLocalDB;AttachDbFilename=G:\\Documents\\DataB
ase\\proba.mdf;Integrated Security=True;Connect Timeout=30";
SqlConnection connection;
public Form1()
{
InitializeComponent();
connection = new SqlConnection(connectionString);
connection.Open();
9

private void button1_Click(object sender, EventArgs e)


{
string sql = "SELECT dept_no,dept_name FROM department";
// connection.Open();
// Создаем объект DataAdapter
SqlDataAdapter adapter = new SqlDataAdapter(sql, connection);
// Создаем объект Dataset
DataSet ds = new DataSet();
// Заполняем Dataset
adapter.Fill(ds);
// Отображаем данные
dataGridView1.DataSource = ds.Tables[0];
}

private void button2_Click(object sender, EventArgs e)


{
string sql = "select
employee.dep_id,employee.emp_fname,employee.emp_lname,employee.emp_no,de
partment.dept_name from employee inner join department ON employee.dep_id =
department.dept_no";
// Создаем объект DataAdapter
SqlDataAdapter adapter = new SqlDataAdapter(sql, connection);
// Создаем объект Dataset
DataSet ds = new DataSet();
// Заполняем Dataset
adapter.Fill(ds);
// Отображаем данные
dataGridView2.DataSource = ds.Tables[0];
}
}
}
В конструкторе формы в DataGridView загружаются данные. Для
загрузки данных создается объект SqlDataAdapter, который принимает
объект подключения и sql-выражение SELECT. Затем создается объект
DataSet и с помощью метода adapter.Fill() в него загружаются данные.
Дальше происходит установка источника данных для DataGridView:
dataGridView1.DataSource = ds.Tables[0];
В качестве источника устанавливается одна из таблиц в DataSet.
Каждая таблица представляет объект DataTable, и в DataSet может быть
определено несколько таких таблиц. Но в данном случае при выборке в
DataSet есть только одна таблица, которую мы можем получить из
коллекции Tables по индексу.