Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
TableAdapters в типизированном наборе данных автоматически заботятся о подключении к базе данных, выполнении команд и заполнении таблицы данных результатами. Однако бывают случаи, когда мы хотим сами позаботиться об этих деталях. В этом руководстве мы узнаем, как получить доступ к настройкам уровня подключения и уровня команд в TableAdapter.
Введение
В серии учебников мы использовали типизированные наборы данных для реализации уровня доступа к данным и бизнес-объектов нашей многоуровневой архитектуры. Как описано в первом руководстве, таблицы данных набора данных Typed служат хранилищами информации, в то время как TableAdapters выполняют роль оболочек для взаимодействия с базой данных с целью извлечения и изменения базовых данных. TableAdapters инкапсулирует сложность работы с базой данных и сохраняет нас от необходимости писать код для подключения к базе данных, выдачи команды или заполнения результатов в DataTable.
Тем не менее, бывают случаи, когда нам нужно углубиться в глубины TableAdapter и писать код, который работает непосредственно с объектами ADO.NET. В руководстве «Оболочка модификаций базы данных в транзакции», например, мы добавили методы в TableAdapter для начала, фиксации и отката транзакций ADO.NET. Эти методы использовали внутренний, вручную созданный SqlTransaction
объект, который назначался объектам SqlCommand
TableAdapter.
В этом руководстве мы рассмотрим, как получить доступ к параметрам подключения к базе данных и уровня команд в 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). Раскрывающийся список в этом первом шаге включает эти базы данных, указанные в файле конфигурации, а также любые другие базы данных в подключениях к данным обозревателя серверов. Если база данных, которую мы хотим использовать, не существует в раскрывающемся списке, можно указать новое подключение к базе данных, нажав кнопку "Создать подключение" и указав необходимые сведения о подключении.
Рис. 1. Первый шаг мастера настройки TableAdapter (щелкните, чтобы просмотреть изображение полного размера)
Давайте уделим момент, чтобы тщательно рассмотреть код для свойства TableAdapter Connection
. Как отмечалось в руководстве по созданию уровня доступа к данным , можно просмотреть автоматически созданный код TableAdapter, перейдя в окно представления классов, свернув до соответствующего класса, а затем дважды щелкнув имя члена.
Перейдите в окно представления классов, перейдя в меню "Вид" и выбрав представление классов (или введя клавиши CTRL+SHIFT+C). В верхней половине окна представления классов выполните детализацию до NorthwindTableAdapters
пространства имен и выберите ProductsTableAdapter
класс. Это отобразит элементы ProductsTableAdapter
в нижней половине Class View, как показано на рис. 2. Дважды щелкните на свойстве Connection
, чтобы просмотреть его код.
Рис. 2. Double-Click свойство подключения в представлении классов для просмотра автоматически созданного кода
Свойство 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
.
Раскрытие настроек Connection-Level
Сведения о подключении должны оставаться инкапсулированными в TableAdapter и недоступны для других слоев архитектуры приложения. Однако могут возникнуть сценарии, когда сведения о уровне подключения TableAdapter должны быть доступны или настраиваемы для страницы запроса, пользователя или ASP.NET.
Давайте расширим ProductsTableAdapter
в Northwind
наборе данных, чтобы добавить свойство ConnectionString
, которое уровень бизнес-логики сможет использовать для чтения или изменения строки подключения, применяемой TableAdapter.
Замечание
Строка подключения — это строка, указывающая сведения о подключении к базе данных, например поставщик, расположение базы данных, учетные данные проверки подлинности и другие параметры, связанные с базой данных. Список шаблонов строк подключения, используемых различными хранилищами данных и поставщиками, см. ConnectionStrings.com.
Как описано в руководстве по созданию уровня доступа к данным , автоматически созданные классы Набора данных можно расширить с помощью частичных классов. Сначала создайте новую вложенную папку в проекте с именем 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
, щелкните на ProductsTableAdapter
в Конструкторе и перейдите в окно "Свойства". Там вы увидите, что ConnectionModifier
установлен на значение по умолчанию Assembly
. Чтобы сделать Connection
свойство доступным вне сборки Typed DataSet, измените свойство ConnectionModifier
на Public
.
Рис. 4.Connection
Уровень специальных возможностей свойства можно настроить с помощью ConnectionModifier
свойства (щелкните, чтобы просмотреть изображение полного размера)
Сохраните набор данных и вернитесь к классу ProductsBLL
. Как и раньше, перейдите к одному из существующих методов и введите Adapter
, а затем нажмите клавишу точки, чтобы открыть IntelliSense. Список должен содержать Connection
свойство, что означает, что теперь можно программно считывать или назначать любые параметры уровня подключения из BLL.
Шаг 3. Изучение свойств Command-Related
TableAdapter состоит из основного запроса, который по умолчанию имеет автоматически созданные операторы INSERT
, UPDATE
, и DELETE
. Эти основной запрос и 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
. Как мы узнали в руководстве по созданию уровня доступа к данным , эти объекты команд можно настроить в окне "Свойства".
В дополнение к основному запросу TableAdapter может включать переменное количество методов, которые при вызове отправляют указанную команду в базу данных. Основной объект команды запроса и объекты команд для всех дополнительных методов хранятся в свойстве TableAdapter CommandCollection
.
Рассмотрим код, созданный ProductsTableAdapter
в Northwind
наборе данных для этих двух свойств, их член-переменных и вспомогательных методов:
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.
Замечание
Adapter
и CommandCollection
свойства помечены как Private
, что означает, что доступ к которым можно получить только из кода в TableAdapter.
Connection
В отличие от свойства, эти модификаторы доступа не настраиваются. Таким образом, если необходимо предоставить свойства уровня команд другим слоям в архитектуре, необходимо использовать подход частичного класса, описанный выше, чтобы предоставить Public
метод или свойство, которое считывает или записывает в Private
объекты команд.
Сводка
TableAdapters в типизированном наборе данных служат для инкапсуляции сложности и сведений о доступе к данным. Используя TableAdapters, мы не должны беспокоиться о написании ADO.NET кода для подключения к базе данных, выдачи команды или заполнения результатов в DataTable. Все это обрабатывается автоматически для нас.
Однако иногда требуется настроить низкоуровневые ADO.NET особенности, например изменение строки подключения или значения времени ожидания команды по умолчанию. TableAdapter имеет автоматически созданные свойства Connection
, Adapter
и CommandCollection
, но они по умолчанию являются Friend
или Private
. Эти внутренние сведения можно раскрыть, расширив TableAdapter с помощью частичных классов, в которых будут включены методы или свойства Public
. Кроме того, модификатор доступа к свойствам TableAdapter Connection
можно настроить с помощью свойства TableAdapter ConnectionModifier
.
Счастливое программирование!
Сведения о авторе
Скотт Митчелл, автор семи книг ASP/ASP.NET и основатель 4GuysFromRolla.com, работает с технологиями Microsoft Web с 1998 года. Скотт работает независимым консультантом, тренером и писателем. Его последняя книга — Sams Teach Yourself ASP.NET 2.0 за 24 часа. С ним можно связаться по адресу mitchell@4GuysFromRolla.com.
Особое спасибо кому
Эта серия учебников была проверена многими полезными рецензентами. Ведущие рецензенты для этого руководства были Бернадетт Ли, Сёрен Якоб Лауритсен, Тереса Мерфи и Хилтон Гейзеноу. Хотите просмотреть мои предстоящие статьи MSDN? Если да, напишите мне на mitchell@4GuysFromRolla.com.