Настройка параметров подключения и параметров уровня команды на уровне доступа к данным (VB)
Адаптеры таблиц в типизированном наборе данных автоматически подключаются к базе данных, выдают команды и заполняют таблицу 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.
При программном доступе к данным обычно используется следующий шаблон:
- Установите подключение к базе данных.
- Выполните команду.
- Для
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 данных сервера Обозреватель. Если нужная база данных отсутствует в раскрывающемся списке, можно указать новое подключение к базе данных, нажав кнопку Создать подключение и указав необходимые сведения о подключении.
Рис. 1. Первый шаг мастера настройки tableAdapter (щелкните, чтобы просмотреть полноразмерное изображение)
Давайте уделим немного времени, чтобы проверить код для свойства TableAdapter.Connection
Как указано в учебнике Создание уровня доступа к данным , мы можем просмотреть автоматически созданный код TableAdapter, перейдя в окно Представление классов, детализировав до соответствующего класса, а затем дважды щелкнув имя элемента.
Перейдите в окно Представление классов, перейдя в меню Вид и выбрав Представление классов (или нажав клавиши CTRL+SHIFT+C). В верхней половине окна Представление классов перейдите к пространству NorthwindTableAdapters
имен и выберите ProductsTableAdapter
класс. При этом элементы будут отображаться ProductsTableAdapter
в нижней половине представления классов, как показано на рис. 2. Дважды щелкните свойство, 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
.
Рис. 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
класс добавляет в класс свойство с именем ConnectionString
ProductsTableAdapter
, которое позволяет любому слою считывать или обновлять строка подключения для базового соединения 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, измените свойство на ConnectionModifier
Public
.
Рис. 4. Уровень Connection
доступности свойств можно настроить с помощью ConnectionModifier
свойства (щелкните для просмотра полноразмерного изображения)
Сохраните dataSet и вернитесь в ProductsBLL
класс . Как и ранее, перейдите к одному из существующих методов и введите Adapter
, а затем нажмите клавишу точки, чтобы открыть IntelliSense. Список должен содержать Connection
свойство, то есть теперь вы можете программно считывать или назначать любые параметры уровня подключения из BLL.
Шаг 3. Изучение свойств Command-Related
TableAdapter состоит из main запроса, который по умолчанию имеет автоматически созданные INSERT
инструкции , UPDATE
и DELETE
. Это main инструкции INSERT
запроса , UPDATE
и DELETE
реализуются в коде TableAdapter в виде объекта адаптера данных ADO.NET через Adapter
свойство . Как и в случае со свойством Connection
Adapter
, тип данных свойства определяется используемым поставщиком данных. Так как в этих руководствах используется поставщик 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.