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

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

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

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

Введение

В рамках серии учебников мы использовали типизированные наборы данных для реализации уровня доступа к данным и бизнес-объектов нашей многоуровневой архитектуры. Как обсуждалось в первом руководстве, таблицы DataTables 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.

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

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

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

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

Шаг 1. Проверка с помощью свойства подключения

Каждый класс 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 _connection As System.Data.SqlClient.SqlConnection
Private Sub InitConnection()
    Me._connection = New System.Data.SqlClient.SqlConnection
    Me._connection.ConnectionString = _
        ConfigurationManager.ConnectionStrings("NORTHWNDConnectionString").ConnectionString
End Sub
Friend Property Connection() As System.Data.SqlClient.SqlConnection
    Get
        If (Me._connection Is Nothing) Then
            Me.InitConnection
        End If
        Return Me._connection
    End Get
    Set
        Me._connection = value
        If (Not (Me.Adapter.InsertCommand) Is Nothing) Then
            Me.Adapter.InsertCommand.Connection = value
        End If
        If (Not (Me.Adapter.DeleteCommand) Is Nothing) Then
            Me.Adapter.DeleteCommand.Connection = value
        End If
        If (Not (Me.Adapter.UpdateCommand) Is Nothing) Then
            Me.Adapter.UpdateCommand.Connection = value
        End If
        Dim i As Integer = 0
        Do While (i < Me.CommandCollection.Length)
            If (Not (Me.CommandCollection(i)) Is Nothing) Then
                CType(Me.CommandCollection(i), _
                    System.Data.SqlClient.SqlCommand).Connection = value
            End If
            i = (i + 1)
        Loop
    End Set
End Property

При создании экземпляра класса TableAdapter переменная-член _connection равна Nothing. При обращении к свойству 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.vb и введите следующий код:

Namespace NorthwindTableAdapters
    Partial Public Class ProductsTableAdapter
        Public Property ConnectionString() As String
            Get
                Return Me.Connection.ConnectionString
            End Get
            Set(ByVal value As String)
                Me.Connection.ConnectionString = value
            End Set
        End Property
    End Class
End Namespace

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

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

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

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

Northwind Откройте dataSet, щелкните 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 WithEvents _adapter As System.Data.SqlClient.SqlDataAdapter
Private Sub InitAdapter()
    Me._adapter = New System.Data.SqlClient.SqlDataAdapter
    
    ... Code that creates the InsertCommand, UpdateCommand, ...
    ... and DeleteCommand instances - omitted for brevity ...
End Sub
Private ReadOnly Property Adapter() As System.Data.SqlClient.SqlDataAdapter
    Get
        If (Me._adapter Is Nothing) Then
            Me.InitAdapter
        End If
        Return Me._adapter
    End Get
End Property
Private _commandCollection() As System.Data.SqlClient.SqlCommand
Private Sub InitCommandCollection()
    Me._commandCollection = New System.Data.SqlClient.SqlCommand(8) {}
    ... Code that creates the command objects for the main query and the ...
    ... ProductsTableAdapter�s other eight methods - omitted for brevity ...
End Sub
Protected ReadOnly Property CommandCollection() As System.Data.SqlClient.SqlCommand()
    Get
        If (Me._commandCollection Is Nothing) Then
            Me.InitCommandCollection
        End If
        Return Me._commandCollection
    End Get
End Property

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

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

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

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

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

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

Public Sub SetCommandTimeout(ByVal timeout As Integer)
    If Me.Adapter.InsertCommand IsNot Nothing Then
        Me.Adapter.InsertCommand.CommandTimeout = timeout
    End If
    If Me.Adapter.DeleteCommand IsNot Nothing Then
        Me.Adapter.DeleteCommand.CommandTimeout = timeout
    End If
    If Me.Adapter.UpdateCommand IsNot Nothing Then
        Me.Adapter.UpdateCommand.CommandTimeout = timeout
    End If
    For i As Integer = 0 To Me.CommandCollection.Length - 1
        If Me.CommandCollection(i) IsNot Nothing Then
            Me.CommandCollection(i).CommandTimeout = timeout
        End If
    Next
End Sub

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

Примечание

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

Сводка

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

Однако в некоторых случаях нам может потребоваться настроить низкоуровневые ADO.NET особенности, такие как изменение строка подключения или значения времени ожидания по умолчанию для подключения или команды. TableAdapter имеет автоматически созданные Connectionсвойства , Adapterи CommandCollection , но по умолчанию они имеют значение Friend или 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.