Поделиться через


Настройка параметров подключения и параметров уровня команды на уровне доступа к данным (C#)

Скотт Митчелл

Загрузить PDF-файл

Адаптеры таблиц в типизированном наборе данных автоматически подключаются к базе данных, выполняют команды и заполняют таблицу DataTable результатами. Однако бывают случаи, когда мы хотим позаботиться об этих деталях самостоятельно, и в этом руководстве мы узнаем, как получить доступ к параметрам подключения к базе данных и на уровне команд в TableAdapter.

Введение

В рамках серии учебников мы использовали типизированные наборы данных для реализации уровня доступа к данным и бизнес-объектов нашей многоуровневой архитектуры. Как обсуждалось в первом руководстве, таблицы DataTable typed DataSet служат репозиториями данных, в то время как TableAdapters выступают в качестве оболочек для взаимодействия с базой данных для получения и изменения базовых данных. TableAdapters инкапсулируют сложность работы с базой данных и избавляют нас от необходимости писать код для подключения к базе данных, выполнения команды или заполнения результатов в таблицу DataTable.

Однако бывают случаи, когда нам нужно зарыться в глубину TableAdapter и написать код, который работает непосредственно с объектами ADO.NET. Например, в руководстве по переносу изменений базы данных в рамках транзакции мы добавили методы в TableAdapter для начала, фиксации и отката ADO.NET транзакций. Эти методы использовали внутренний, созданный SqlTransaction вручную объект, назначенный объектам TableAdapter SqlCommand .

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

Работа с данными с помощью ADO.NET

Microsoft платформа .NET Framework содержит множество классов, предназначенных специально для работы с данными. Эти классы, находящиеся в System.Data пространстве имен, называются классами ADO.NET . Некоторые классы в ADO.NET зонтично привязаны к конкретному поставщику данных. Поставщик данных можно рассматривать как канал связи, который позволяет передавать информацию между классами ADO.NET и базовым хранилищем данных. Существуют универсальные поставщики, такие как OleDb и ODBC, а также поставщики, специально разработанные для конкретной системы баз данных. Например, хотя можно подключиться к базе данных Microsoft SQL Server с помощью поставщика OleDb, поставщик SqlClient гораздо эффективнее, так как он был разработан и оптимизирован специально для SQL Server.

При программном доступе к данным обычно используется следующий шаблон:

  • Установите подключение к базе данных.
  • Выполните команду .
  • Для SELECT запросов работайте с результирующей записью.

Существуют отдельные ADO.NET классы для выполнения каждого из этих шагов. Например, чтобы подключиться к базе данных с помощью поставщика SqlClient, используйте SqlConnection класс . Чтобы выполнить INSERTкоманду , UPDATE, DELETEили SELECT в базе данных, используйте SqlCommand класс .

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

Шаг 1. Проверка с помощью свойства connection

Каждый класс TableAdapter имеет Connection свойство , указывающее сведения о подключении к базе данных. Тип данных и ConnectionString значение этого свойства определяются параметрами, выбранными в мастере настройки TableAdapter. Помните, что при первом добавлении TableAdapter в типизированный набор данных мастер запрашивает источник базы данных (см. рис. 1). Раскрывающийся список на этом первом шаге включает базы данных, указанные в файле конфигурации, а также другие базы данных в Connections данных сервера Обозреватель. Если база данных, которую мы хотим использовать, не существует в раскрывающемся списке, можно указать новое подключение к базе данных, нажав кнопку Создать подключение и указав необходимые сведения о подключении.

Первый шаг мастера настройки TableAdapter

Рис. 1. Первый шаг мастера настройки TableAdapter (щелкните для просмотра полноразмерного изображения)

Рассмотрим код свойства TableAdapter Connection . Как отмечалось в учебнике Создание уровня доступа к данным , мы можем просмотреть автоматически созданный код TableAdapter, перейдя в окно Представление классов, детализировав соответствующий класс, а затем дважды щелкнув имя члена.

Перейдите в окно Представление классов, перейдя в меню Вид и выбрав Представление классов (или нажав клавиши CTRL+SHIFT+C). В верхней части окна Представление классов перейдите к пространству NorthwindTableAdapters имен и выберите ProductsTableAdapter класс . Элементы будут отображаться ProductsTableAdapter в нижней половине представления классов, как показано на рисунке 2. Дважды щелкните свойство, Connection чтобы просмотреть его код.

Дважды щелкните свойство Connection в представлении классов, чтобы просмотреть автоматически созданный код.

Рис. 2. Double-Click свойства Connection в представлении классов для просмотра его автоматически созданного кода

Ниже приведены свойства TableAdapter Connection и другой код, связанный с подключением:

private System.Data.SqlClient.SqlConnection _connection;
private void InitConnection() {
    this._connection = new System.Data.SqlClient.SqlConnection();
    this._connection.ConnectionString = 
        ConfigurationManager.ConnectionStrings["NORTHWNDConnectionString"].ConnectionString;
}
internal System.Data.SqlClient.SqlConnection Connection {
    get {
        if ((this._connection == null)) {
            this.InitConnection();
        }
        return this._connection;
    }
    set {
        this._connection = value;
        if ((this.Adapter.InsertCommand != null)) {
            this.Adapter.InsertCommand.Connection = value;
        }
        if ((this.Adapter.DeleteCommand != null)) {
            this.Adapter.DeleteCommand.Connection = value;
        }
        if ((this.Adapter.UpdateCommand != null)) {
            this.Adapter.UpdateCommand.Connection = value;
        }
        for (int i = 0; (i < this.CommandCollection.Length); i = (i + 1)) {
            if ((this.CommandCollection[i] != null)) {
                ((System.Data.SqlClient.SqlCommand)
                    (this.CommandCollection[i])).Connection = value;
            }
        }
    }
}

При создании экземпляра класса TableAdapter переменная-член _connection равна null. При обращении к свойству Connection сначала проверяется, был ли _connection создан экземпляр переменной-члена. Если это не так, InitConnection вызывается метод , который создает _connection экземпляр и задает его ConnectionString свойству значение строка подключения, указанное на первом шаге мастера конфигурации TableAdapter.

Свойство Connection также можно назначить объекту SqlConnection . При этом новый SqlConnection объект связывается с каждым из объектов TableAdapter SqlCommand .

Шаг 2. Предоставление параметров Connection-Level

Сведения о подключении должны оставаться инкапсулированными в TableAdapter и не должны быть доступны другим уровням в архитектуре приложения. Однако могут возникать ситуации, когда сведения об уровне подключения TableAdapter должны быть доступны или настраиваемы для запроса, пользователя или страницы ASP.NET.

Давайте расширим ProductsTableAdapter в Northwind dataSet, чтобы включить ConnectionString свойство, которое может использоваться уровнем бизнес-логики для чтения или изменения строка подключения, используемых TableAdapter.

Примечание

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

Как описано в учебнике Создание уровня доступа к данным , автоматически создаваемые классы Typed DataSet можно расширить с помощью разделяемых классов. Сначала создайте вложенную папку в проекте с именем ConnectionAndCommandSettings под папкой ~/App_Code/DAL .

Добавление вложенной папки с именем ConnectionAndCommandSettings

Рис. 3. Добавление вложенной папки с именем ConnectionAndCommandSettings

Добавьте новый файл класса с именем ProductsTableAdapter.ConnectionAndCommandSettings.cs и введите следующий код:

using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
namespace NorthwindTableAdapters
{
    public partial class ProductsTableAdapter
    {
        public string ConnectionString
        {
            get
            {
                return this.Connection.ConnectionString;
            }
            set
            {
                this.Connection.ConnectionString = value;
            }
        }
    }
}

Этот разделяемый public класс добавляет в класс свойство с именем ConnectionStringProductsTableAdapter , которое позволяет любому уровню считывать или обновлять строка подключения для базового подключения TableAdapter.

Создав (и сохранив) этот разделяемый ProductsBLL класс, откройте класс . Перейдите к одному из существующих методов и введите и Adapter нажмите клавишу точки, чтобы открыть IntelliSense. Вы должны увидеть новое ConnectionString свойство, доступное в IntelliSense, что означает, что вы можете программно считывать или настраивать это значение из BLL.

Предоставление доступа ко всему объекту connection

Этот разделяемый класс предоставляет только одно свойство базового объекта подключения: ConnectionString. Если вы хотите сделать весь объект подключения доступным за пределами TableAdapter, можно также изменить Connection уровень защиты свойства. Автоматически созданный код, рассмотренный на шаге 1, показал, что свойство TableAdapter Connection помечено как internal, то есть доступ к нему могут получить только классы в той же сборке. Однако его можно изменить с помощью свойства TableAdapter ConnectionModifier .

Northwind Откройте набор данных, щелкните ProductsTableAdapter в Designer и перейдите к окно свойств. Там вы увидите ConnectionModifier значение по умолчанию , . Assembly Чтобы сделать Connection свойство доступным вне сборки Typed DataSet, измените свойство на ConnectionModifierPublic.

Уровень доступности свойства подключения можно настроить с помощью свойства ConnectionModifier.

Рис. 4. Уровень Connection доступности свойства можно настроить с помощью ConnectionModifier свойства (щелкните для просмотра полноразмерного изображения)

Сохраните DataSet и вернитесь в ProductsBLL класс . Как и раньше, перейдите к одному из существующих методов и введите , Adapter а затем нажмите клавишу точки, чтобы открыть IntelliSense. Список должен содержать Connection свойство, то есть теперь вы можете программно считывать или назначать любые параметры уровня подключения из BLL.

TableAdapter состоит из main запроса, который по умолчанию имеет автоматически созданные INSERTинструкции , UPDATEи DELETE . Это main инструкции INSERTзапроса , UPDATEи DELETE реализованы в коде TableAdapter в виде объекта адаптера данных ADO.NET через Adapter свойство . Как и в случае со свойством ConnectionAdapter , тип данных свойства определяется используемым поставщиком данных. Так как в этих руководствах используется поставщик SqlClient, Adapter свойство имеет тип SqlDataAdapter.

Свойство TableAdapter Adapter имеет три свойства типа SqlCommand , которые оно использует для выдачи инструкций INSERT, UPDATEи DELETE :

  • InsertCommand
  • UpdateCommand
  • DeleteCommand

Объект SqlCommand отвечает за отправку определенного запроса в базу данных и имеет такие свойства, как , CommandTextкоторый содержит нерегламентированный sql-оператор или хранимую процедуру для выполнения; и Parameters, который является коллекцией SqlParameter объектов . Как мы видели в руководстве По созданию уровня доступа к данным, эти объекты команд можно настроить с помощью окно свойств.

Помимо main запроса, TableAdapter может включать в себя переменное количество методов, которые при вызове отправляют указанную команду в базу данных. Объект команды main запроса и объекты команд для всех дополнительных методов хранятся в свойстве TableAdapter.CommandCollection

Рассмотрим код, созданный ProductsTableAdapter в Northwind DataSet для этих двух свойств, а также их вспомогательных переменных-членов и вспомогательных методов:

private System.Data.SqlClient.SqlDataAdapter _adapter;
private void InitAdapter() {
    this._adapter = new System.Data.SqlClient.SqlDataAdapter();
    
    ... Code that creates the InsertCommand, UpdateCommand, ...
    ... and DeleteCommand instances - omitted for brevity ...
}
private System.Data.SqlClient.SqlDataAdapter Adapter {
    get {
        if ((this._adapter == null)) {
            this.InitAdapter();
        }
        return this._adapter;
    }
}
private System.Data.SqlClient.SqlCommand[] _commandCollection;
private void InitCommandCollection() {
    this._commandCollection = new System.Data.SqlClient.SqlCommand[9];
    ... Code that creates the command objects for the main query and the ...
    ... ProductsTableAdapter�s other eight methods - omitted for brevity ...
}
protected System.Data.SqlClient.SqlCommand[] CommandCollection {
    get {
        if ((this._commandCollection == null)) {
            this.InitCommandCollection();
        }
        return this._commandCollection;
    }
}

Код свойств Adapter и CommandCollection тесно имитирует Connection код свойства . Существуют переменные-члены, которые содержат объекты, используемые свойствами . Методы доступа к свойствам get начинаются с проверки, является ли соответствующая переменная-член .null Если это так, вызывается метод инициализации, который создает экземпляр переменной-члена и назначает основные свойства, связанные с командой.

Шаг 4. Предоставление параметров Command-Level

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

Так как TableAdapter имеет только одно Connection свойство, код для предоставления параметров уровня подключения довольно прост. Изменение параметров на уровне команд немного сложнее, так как TableAdapter может иметь несколько объектов команд — InsertCommand, UpdateCommandи DeleteCommand, а также переменное количество объектов команд в свойстве CommandCollection . При обновлении параметров на уровне команд эти параметры необходимо распространить на все объекты команд.

Например, представьте, что в TableAdapter были определенные запросы, выполнение которым заняло чрезвычайно много времени. При использовании TableAdapter для выполнения одного из этих запросов может потребоваться увеличить свойство объекта CommandTimeoutкоманды. Это свойство указывает время ожидания выполнения команды в секундах и значение по умолчанию — 30.

Чтобы разрешить настройку CommandTimeout свойства bLL, добавьте следующий public метод в ProductsDataTable с помощью файла разделяемого класса, созданного на шаге 2 (ProductsTableAdapter.ConnectionAndCommandSettings.cs):

public void SetCommandTimeout(int timeout)
{
    if (this.Adapter.InsertCommand != null)
        this.Adapter.InsertCommand.CommandTimeout = timeout;
    if (this.Adapter.DeleteCommand != null)
        this.Adapter.DeleteCommand.CommandTimeout = timeout;
    if (this.Adapter.UpdateCommand != null)
        this.Adapter.UpdateCommand.CommandTimeout = timeout;
    for (int i = 0; i < this.CommandCollection.Length; i++)
        if (this.CommandCollection[i] != null)
            this.CommandCollection[i].CommandTimeout = timeout;
}

Этот метод можно вызвать из BLL или уровня презентации, чтобы задать время ожидания команды для всех проблем с командами экземпляром TableAdapter.

Примечание

Свойства Adapter и CommandCollection помечены как private, то есть доступ к им можно получить только из кода в TableAdapter. Connection В отличие от свойства, эти модификаторы доступа не настраиваются. Таким образом, если необходимо предоставить свойства уровня команд другим уровням архитектуры, необходимо использовать описанный выше подход к разделяемым классам, чтобы предоставить public метод или свойство, которое считывает или записывает private в объекты команд.

Сводка

Адаптеры TableAdapters в типизированном наборе данных служат для инкапсуляции сведений о доступе к данным и сложности. Используя TableAdapters, нам не нужно беспокоиться о написании ADO.NET кода для подключения к базе данных, выполнения команды или заполнения результатов в таблицу DataTable. Все это обрабатывается автоматически для нас.

Однако в некоторых случаях нам может потребоваться настроить низкоуровневые ADO.NET особенности, например изменить строка подключения или значения по умолчанию для подключения или времени ожидания команды. TableAdapter имеет автоматически созданные Connectionсвойства , Adapterи CommandCollection , но по умолчанию они имеют значение internal или private. Эти внутренние сведения можно предоставить, расширив TableAdapter с помощью разделяемых классов для включения public методов или свойств. Кроме того, модификатор доступа к свойству TableAdapter Connection можно настроить с помощью свойства TableAdapter s ConnectionModifier .

Счастливого программирования!

Об авторе

Скотт Митчелл( Scott Mitchell), автор семи книг ASP/ASP.NET и основатель 4GuysFromRolla.com, работает с веб-технологиями Майкрософт с 1998 года. Скотт работает независимым консультантом, тренером и писателем. Его последняя книга Sams Teach Yourself ASP.NET 2.0 в 24 часах. Он может быть доступен в mitchell@4GuysFromRolla.com. или через его блог, который можно найти по адресу http://ScottOnWriting.NET.

Особая благодарность

Эта серия учебников была рассмотрена многими полезными рецензентами. Ведущим рецензентом этого руководства были Бернадет Ли, Срен Джейкоб Лауритсен, Тереса Мерфи и Хилтон Гейзенов. Хотите просмотреть предстоящие статьи MSDN? Если да, опустите мне строку на mitchell@4GuysFromRolla.com.