Подключение к базе данных

57

Первое, что нужно сделать при работе с поставщиком данных — это установить сеанс с источником данных с помощью объекта подключения (порожденного, как вы помните, от DbConnection). У объектов подключения .NET имеется форматированная строка подключения, которая содержит ряд пар имя/значение, разделенных точками с запятой. Эта информация содержит имя машины, к которой нужно подключиться, необходимые параметры безопасности, имя базы данных на этой машине и другую информацию, зависящую от поставщика.

В следующем коде иллюстрируется создание, открытие и закрытие соединения с базой данных SqlServer:

// Создание открытого подключения
using (SqlConnection cn = new SqlConnection())
{
      cn.ConnectionString = @"Data Source=MICROSOF-1EA29E\SQLEXPRESS;Initial Catalog=AutoLot;" +
          "Integrated Security=SSPI;Pooling=False";
      cn.Open();
      // Работа с базой данных
      cn.Close();
}

Из приведенного выше кода можно понять, что имя Initial Catalog относится к базе данных, с которой нужно установить сеанс. Имя Data Source определяет имя машины, на которой расположена база данных. Элемент (local) позволяет указать текущую локальную машину (независимо от конкретного имени этой машины), а элемент \SQLEXPRESS сообщает поставщику SQL Server, что вы подключаетесь к стандартной инсталляции SQL Server Express (если вы создали AutoLot с помощью полной версии SQL Server 2005 или более ранней, укажите Data Source=(local)). В данном примере я использовал вместо (local) полное название имени компьютера (MICROSOF-1EA29E), на котором развернута версия SQL Server.

Кроме того, можно указать любое количество элементов, которые задают полномочия безопасности. В нашем примере имени Integrated Security присвоено значение SSPI (что эквивалентно true), которое использует для аутентификации пользователя текущие полномочия учетной записи Windows.

Назначение каждой пары имя/значение для вашей СУБД можно узнать в документации по NET Framework 4.0 SDK, в описании свойства ConnectionString объекта подключения для вашего поставщика данных.

При наличии строки подключения вызов Open() устанавливает соединение с СУБД. В дополнение к членам ConnectionString, Open() и Close() объект подключения содержит ряд членов, которые позволяют настроить дополнительные параметры подключения, например, время тайм-аута и информацию, относящуюся к транзакциям.

Ниже приведены некоторые члены базового класса DbConnection:

BeginTransaction()

Используется для начала транзакции базы данных

ChangeDatabase()

Изменяет базу данных для открытого подключения

ConnectionTimeout

Свойство только для чтения. Возвращает время ожидания при установке подключения, после которого ожидание прекращается и выдается сообщение об ошибке (по умолчанию 15 секунд). Для изменения этого времени нужно изменить в строке подключения сегмент Connect Timeout (например, Connect Timeout=30)

Database

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

DataSource

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

GetSchema()

Этот метод возвращает объект DataTable, содержащий информацию схемы из источника данных

State

Свойство только для чтения. Содержит текущее состояние подключения в виде одного из значений перечисления ConnectionState

Свойства типа DbConnection предназначены в основном только для чтения и поэтому нужны, если требуется получить характеристики подключения во время выполнения. Если понадобится изменить стандартные значения, необходимо будет изменить саму строку подключения. Например, можно изменить время тайм-аута с 15 на 30 секунд:

cn.ConnectionString = @"Data Source=..." + "Connect Timeout=30"

Программная работа со строками подключения может оказаться несколько затруднительной, поскольку они часто представлены в виде строковых литералов, которые трудно обрабатывать и контролировать на наличие ошибок. Поставщики данных ADO.NET, разработанные Microsoft, поддерживают объекты построителей строк подключения (connection string builder object) (аналог StringBuilder), которые позволяют устанавливать пары имя/значение с помощью строго типизированных свойств. Рассмотрим следующую модификацию нашего метода Main():

// Создание строки подключения с помощью объекта построителя
            SqlConnectionStringBuilder connect =
                new SqlConnectionStringBuilder();
            connect.InitialCatalog = "Autolot";
            connect.DataSource = @"(local)\SQLEXPRESS";
            connect.ConnectTimeout = 30;
            connect.IntegratedSecurity = true;

            // Создание открытого подключения
            using (SqlConnection cn = new SqlConnection())
            {
                cn.ConnectionString = connect.ConnectionString;
                cn.Open();
                // Работа с базой данных
                cn.Close();
            }

В этом варианте создается экземпляр SqlConnectionStringBuilder, устанавливаются его свойства, и выбирается внутренняя строка из свойства ConnectionString. Здесь использован стандартный конструктор типа. При этом можно также создать экземпляр объекта построителя для строки подключения поставщика данных, передав в качестве отправной точки существующую строку подключения (это может оказаться удобным при динамическом чтении значений из файла App.config).

Эффективное использование соединений

В общем случае при использовании в .NET таких скудных ресурсов, как соединения с базой данных, окна или графические объекты, хорошим тоном является закрытие ресурса после работы с ним. Хотя проектировщики .NET реализовали автоматическую сборку мусора, которая рано или поздно произойдет, необходимо освобождать ресурсы как можно раньше, чтобы избежать дефицита ресурсов.

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

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

Вариант обеспечения очистки ресурсов состоит в применении блоков try... catch... finally, и он гарантирует закрытие любых открытых соединений внутри блока finally. Рассмотрим краткий пример:

using (SqlConnection cn = new SqlConnection())
            {
                cn.ConnectionString = connect.ConnectionString;
                try
                {
                    //Открыть подключение
                    cn.Open();
                }
                catch (SqlException ex)
                {
                    // Протоколировать исключение
                    Console.WriteLine(ex.Message);
                }
                finally
                {
                    // Гарантировать освобождение подключения
                    cn.Close();
                }
            }
Пройди тесты
Лучший чат для C# программистов