Практическая работа по теме 3. "Наборы данных"

advertisement
Практическая работа по теме 3. "Наборы
данных"
Передача данных из источника данных в объект DataSet с помощью объекта
DataAdapter. Обновление данных в связанных таблицах. Отображение данных:
объект DataView. Привязка данных в формах Windows.
Оглавление
Задание
Задание
Задание
Задание
1.
2.
3.
4.
Передача данных из источника данных в DataSet
Обновление данных в связанных таблицах
Отображение таблиц и полей: объект DataView
Привязка данных в формах Windows
Задание 1. Определение метаданных для объекта
DataTable
Цель
Научиться управлять процессом передачи данных от источника данных к
DataSet.
Решение
Изучить объект модели ADO.NET DataAdapter, его свойства и методы.
Обсуждение
Объект DataAdapter является промежуточным звеном между объектом DataSet
и физическим источником данных. Он играет роль связующего звена между двумя
компонентами ADO.NET: подключенным к источнику данных компонентом
провайдеров данных .NET и неподключенным к источнику данных компонентом
объектов DataSet.
В структуре провайдеров данных .NET объект DataAdapter занимает
центральное место. Каждый провайдер имеет собственную реализацию объекта
DataAdapter, например, SqlDataAdapter, OledbDataAdapter, OdbcDataAdapter. На
рис. 3.1. приведена схема использования объекта DataAdapter в модели
ADO.NET, его свойств и методов.
Основным назначением объекта DataAdapter является управление процессом
передачи данных от источника данных к объекту DataSet и от объекта DataSet к
источнику данных. Это выполняется с помощью небольшого набора свойств и
методов, которые мы должны изучить. Основными методами объекта DataAdapter
являются Fill и Update. Метод Fill наполняет объект DataAdapter данными,
полученными от источника данных, а метод Update обновляет источник данных в
соответствии с изменениями данных в таблицах объекта DataSet.
Объект
DataAdapter
содержит
набор
из
четырех
свойств:
SelectCommand, InsertCommand, UpdateCommand и DeleteCommand, которые
являются объектами ADO.NET типа Command, сконфигурированными для
выполнения
одноименных
операций.
Например,
объект
SelectCommand
выполняется при вызове метода Fill объекта DataAdapter, а остальные объекты
выполняются для каждой измененной записи при вызове метода Update объекта
DataAdapter.
Рис. 3.1. Схема работы объекта DataAdapter как связующего звена между источником
данных и объектом DataSet
Таким образом, разработчики базы данных обладают полным контролем над
этими командами, которые позволяют настраивать команды, используемые для
операций вставки, обновления и удаления. Наконец, коллекция TableMappings
объектов DataTableMapping позволяет указать соответствие между таблицей
источника данных и объектом DataTable.
Для использования объекта DataAdapter требуется подключение к базе данных
и команда Select (это минимальный набор средств и методов). Для этого можно
использовать объекты Connection и Command, то есть создать их,
сконфигурировать и присвоить их свойства Connection и SelectCommand объекту
DataAdapter.
Private
daEmployees
As
New
SqlDataAdapter
Dim cnn As New SqlConnection("server=Persist
Security
Info=False;Integrated
Security=SSPI;
database=HumanResources;
server=abrzh")
daEmployees.SelectCommand = New SqlCommand
daEmployees.SelectCommand.Connection
=
cnn
daEmployees.SelectCommand.CommandText
=
"SELECT EmployeeID, FirstName"
Можно воспользоваться другим приемом - использовать конструктор объекта
DataAdapter с двумя строковыми параметрами: один для команды SELECT, а
второй для строки подключения, как показано ниже.
Dim daDep As SqlDataAdapter = New SqlDataAdapter
("select * from Departments", "server=Persist Security
Info=False;Integrated
Security=SSPI;
database=EmployeeInfo; server=abrzh")
Попробуем теперь вызвать метод Fill для извлечения данных из базы данных
EmployeeInfo
и
загрузки
их
в
объект
DataSet.
1. Создайте базу данных EmployeeInfo средствами Visual Studio.Net в SQL Server.
Модель базы данных представлена на рис. 3.2.
Рис. 3.2. Модель базы данных EmployeeInfo
2.
Установите
связи
и
заполните
таблицы
необходимой
информацией.
3. Откройте форму "Data Set" проекта к практикуму по теме "Отсоединенная
модель
программирования".
4. Создайте новую кнопку DataAdapterFill. Вставьте в процедуру обработки
щелчка по командной кнопке код, приведенный ниже. Не забудьте импортировать
необходимые пространства имен:
Imports
System.Data,
System.Data.SqlClient
Private
Sub
Button7_Click(ByVal
sender
As
System.Object, ByVal e As System.EventArgs) Handles
Button7.Click
ReadData()
End Sub
Код процедуры общего назначения для чтения данных из источника данных
ReadData():
Private
Sub
ReadData()
Dim
rows
As
Integer
Dim
daDep
As
SqlDataAdapter
=
New
SqlDataAdapter("select
*
from
Departments",
"server=Persist
Security
Info=False;
Integrated
database=EmployeeInfo;
dsE
=
New
rows
=
daDep.Fill(dsE,
DisplayDataset(dsE)
End Sub
Security=SSPI;
server=abrzh")
DataSet
"Departments")
После создания объекта daDep с двумя аргументами, которые содержат
команду Select и строку подключения, вызывается метод Fill для наполнения
данными таблицы Departments набора данных dsE. Метод Fill также возвращает
количество записей, которые включены (или обновлены) в набор данных dsE. При
выполнении метода Fill провайдером данных неявно выполняются следующие
действия:
 Для объекта SelectCommand открывается подключение к источнику
данных, если оно еще не открыто.
 Выполняется команда, указанная в свойстве CommandText объекта
SelectCommand (вместе с параметрами, если таковые имеются).
 Создается объект DataReader для возвращения имен полей и типов,
использованных для создания нового объекта DataTable в указанном
наборе данных DataSet, если этого объекта еще не существует.
 Объект DataReader используется для извлечения данных и вставки их
в таблицу.
 Объект DataReader закрывается.
 Подключение к источнику данных закрывается, если оно было открыто
объектом DataReader, в противном случае оно остается открытым.
При выполнении одной команды по отношению к источнику данных (наш с
вами случай) обычно проще и эффективнее создавать объекты Command и
Connection неявно при создании объекта DataAdapter (именно так мы с вами и
поступили). Однако при выполнении нескольких команд по отношению к одному
источнику данных эффективнее создавать объект Connection явно и затем
присвоить его объекту DataAdapter. Это позволяет поддерживать подключение
постоянно открытым, без часто повторяющихся операций его открытия и
закрытия, что снижает производительность. Эквивалентный код представлен
ниже.
Private
Sub
ReadData1()
Dim
rows
As
Integer
Dim
daDep
As
New
SqlDataAdapter
Dim cnn As New SqlConnection("server=Persist
Security
Info=False;
Integrated
Security=SSPI;
database=EmployeeInfo;
server=abrzh")
Dim cmdSelect As New SqlCommand("select * from
Departments")
dsE
=
New
DataSet
cmdSelect.Connection
=
cnn
daDep.SelectCommand
=
cmdSelect
cnn.Open()
rows
=
daDep.Fill(dsE,
"Departments")
DisplayDataset(dsE)
cnn.Close()
End Sub
Конечно, для эффективного использования явно созданных объектов cnn и
cmdSelect желательно, чтобы количество операций с базой данных было
достаточно большим.
Еще одно дополнение к написанному коду. Методу Fill мы передаем ссылку на
набор данных dsE и имя таблицы Departments, в которую вставляются данные:
rows = daDep.Fill(dsE, "Departments")
Возможны другие варианты вызова метода Fill. Вместо имени таблицы можно
было бы передать ссылку на объект DataTable или передать только ссылку на
объект DataSet, а метод Fill в таком случае по умолчанию загрузит данные в
объект DataTable по имени Table.
rows = daDep.Fill(dsE)
Для указания информативных имен таблиц Table, Table1 и так далее,
используется коллекция объектов DataTableMapping и метод Add:
daDep.TableMappings.Add("Table",
"Отделы")
daDep.TableMappings.Add("Table1", "Сотрудники")
Самостоятельно
Добавьте в процедуру ReadData() описание еще одно адаптера с другой
командой Select для загрузки данных из таблицы Employees. Скомпонуйте проект,
щелкните по кнопке DataAdapterFill, в поле со списком, как и прежде, будет
отображена информация о содержании набора данных dsE, но теперь она
извлекается из базы данных под управлением SQL Server, а не генерируется
локально кодом приложения (рис. 3.3).
Рис. 3.3. Данные из таблиц базы данных, управляемой SQL Server (не из локальной
версии, как ранее)
Для установления родительско-дочерних связей между записями в этих
таблицах можно создать объект DataRelation, который служит отношением между
ними.
dsE.Relations.Add("D_E",
dsE.Tables("Departments").Columns("ID"),
dsE.Tables("Employees").Columns("DepartmentID"))
Задание 2. Обновление данных в связанных
таблицах
Цель
Сохранить все изменения в источнике данных в соответствии с изменениями в
таблицах набора данных DataSet.
Решение
Использовать метод Update объекта DataAdapter,. который анализирует
изменения в указанной таблице набора данных (или сразу во всех таблицах, если
ни одна из них не указана явно).
Обсуждение
Для каждой измененной записи по отношению к источнику данных
выполняется команда вставки, обновления или удаления с помощью
соответствующего
объекта
InsertCommand,
UpdateCommand
или
DeleteCommand.
Каждая измененная запись обновляется отдельно, а не как часть транзакции
или пакетной операции. Причем порядок обновления записей определяется
порядком их расположения в объекте DataTable.
Для явного управления порядком выполнения операций для заданной таблицы
можно использовать метод GetChanges, который доступен как на уровне объекта
DataSet, так и на уровне объекта DataTable. Этот метод используются для
извлечения отдельных наборов записей с разными состояниями записей.
Предположим, мы обновляем нашу базу данных EmployeesInfo данными из
объекта ds, передавая их в базу данных с помощью объекта da. Причем сначала
требуется выполнить все удаления, затем все обновления, а потом все вставки
записей. Это можно сделать, трижды вызывая метод GetChanges с указанием
соответствующих разных состояний записей. После каждого вызова метода
GetChanges вызывается метод Update объекта DataAdapter с передачей объекта
DataTable, возвращенного методом GetChanges.
Dim
dt
=
ds.Tables("Table")
Dim
tab
As
New
DataTable
tab
=
dt.GetChanges(DataRowState.Deleted)
If
Not
tab
Is
Nothing
Then
da.Update(tab)
End
If
tab
=
dt.GetChanges(DataRowState.Modified)
If
Not
da.Update(tab)
End
tab
=
If
Not
da.Update(tab)
End If
tab
Is
Nothing
Then
If
dt.GetChanges(DataRowState.Added)
tab
Is
Nothing
Then
Объект DataAdapter не создает автоматически команды INSERT, UPDATE и
DELETE для обновления источника данных в соответствии с изменениями данных
в объекте DataSet. Эти команды можно указать одним из следующих способов:
 Использовать объект CommandBuilder для автоматической генерации
команд во время выполнения приложения;
 Явно запрограммировать эти команды;
 Использовать компонент DataAdapter Design-Time Component и мастер
конфигурирования объекта DataAdapter Configuration Wizard.
Рассмотрим использование объекта CommandBuilder - это самый простой
способ выполнения команд INSERT, UPDATE и DELETE. Следует иметь в виду, что
объект CommandBuilder имеет некоторые ограничения в использовании, так,
например, он не подлежит конфигурированию (настройке), предназначен только
для одной таблицы, не учитывает связи таблицы с другими таблицами.
1. Создайте в проекте новую форму, разместите на ней элемент DataGrid для
отображения записей таблиц и две командные кнопки Fill и Update (рис. 3.4).
2. В верхней части кода выполните импортирование следующих пространств
имен:
Imports
Imports System.Data.SqlClient
System.Data
3. Для каждой из кнопок введите соответствующий код, представленный ниже.
Dim cnn As New SqlConnection("Persist Security
Info=False;Integrated
Security=SSPI;database=EmployeeInfo;server=abrzh")
Dim
ds
As
DataSet
'Код
обработки
щелчка
по
кнопке
Fill
Private
Sub
Button1_Click(ByVal
sender
As
System.Object, ByVal e As System.EventArgs) Handles
Button1.Click
Dim da As New SqlDataAdapter("select * from
Departments",
cnn)
DataGrid1.DataSource
=
Nothing
ds
=
New
DataSet
da.Fill(ds,
"Departments")
da = New SqlDataAdapter("select * from Employees",
cnn)
da.Fill(ds, "Employees")
4. 'Установление родительско-дочерних отношений между таблицами.
ds.Relations.Add("Departments_Employees",
ds.Tables("Departments").Columns("ID"),
ds.Tables("Employees").Columns("DepartmentID"))
DataGrid1.DataSource
=
ds
End
Sub
Private
Sub
Button2_Click(ByVal
sender
As
System.Object, ByVal e As System.EventArgs) Handles
Button2.Click 'Код обработки щелчка по кнопке
Update
5. 'Создание адаптеров данных
Dim daDep As New SqlDataAdapter("select * from
Departments",
cnn)
Dim daEmp As New SqlDataAdapter("select * from
Employees",
cnn)
Dim cbDep As New SqlCommandBuilder(daDep)
Dim cbEmp As New SqlCommandBuilder(daEmp)
6. 'Внесение изменений в таблицы в "правильном" порядке
Dim
tab
As
New
DataTable
'Удаление
записей
в
дочерней
таблице
tab
=
ds.Tables("Employees").GetChanges(DataRowState.Deleted)
If
Not
tab
Is
Nothing
Then
daEmp.Update(tab)
End If
7. 'Все измененные записи в родительской таблице.
tab
=
ds.Tables("Departments").GetChanges
If
Not
tab
Is
Nothing
Then
daDep.Update(tab)
End If
8. 'Новые или измененные записи в дочерней таблице.
tab
=
ds.Tables("Employees").GetChanges(DataRowState.Added
Or
DataRowState.Modified)
If
Not
tab
Is
Nothing
Then
daEmp.Update(tab)
End
If
End Sub
Рис. 3.4. Отображение связанных таблиц с помощью элемента управления DataGrid
Самостоятельно
Скомпонуйте проект Departments and Employees и проверьте полученное
приложение, выполнив перечисленные ниже действия:
 Запустите полученное приложение и щелкните на кнопке Fill. Это
должно привести к вставке данных в объект DataSet из базы данных
EmployeeInfo. Однако строка кода DataGrid1.DataSource = ds связывает с
сеткой весь объект DataSet, а не какую-то одну таблицу DataTable.
Поэтому сетка содержит раскрывающийся список (рис. 3.4).
 Щелкните на пиктограмме "плюс" и раскройте список ссылок на две
таблицы объекта DataSet.
 Раскройте таблицу Departments, введите новые данные, удалите или
измените имеющиеся строки. Проверьте изменения в источнике, для
этого нажмите кнопку Update, затем снова нажмите кнопку Fill.
 Проделайте аналогичные изменения с записями таблицы Employees.
Успешное удаление записи из родительской таблицы Departments вместе с ее
дочерними записями в таблице Employees возможно благодаря заданному по
умолчанию ограничению ForeignConstraint для отношения Department_Employees.
Ограничение заключается в каскадном обновлении (удалении) данных в
родительской и дочерней таблицах.
Задание 3. Отображение таблиц и полей: объект
DataView
Цель
При проектировании интерфейса пользователя научиться изменять способ
отображения данных из таблиц набора данных DataSet.
Решение
Использовать объект DataView, позволяющий создавать разные представления
данных для объекта DataTable.
Обсуждение
Объект DataView обладает следующими свойствами, которые
настраивать способ отображения данных из объекта DataTable:
позволяют
 Порядок сортировки (нисходящий или восходящий) по одному или
нескольким полям.
 Выражение для фильтрации записей, которое указывает критерии
отображения записей на основе значений полей.
 Фильтр состояния записей, который указывает критерии отображения
записей на основе состояния записи.
Объект DataView - полностью динамическое представление данных, то есть все
изменения в таблице-источнике немедленно отображаются в объекте DataView.
Каждый объект DataView является представлением только одной таблицы и не
может быть объединением нескольких таблиц. Не смотря на то, что объект
DataView очень похож на таблицу, он не может использоваться как таблица, в нем
нельзя исключать поля, которые присутствуют в таблице-источнике, не возможно
включать дополнительные поля, например, вычисляемые поля, которых нет в
таблице-источнике. Другими словами, объект DataView является представлением
таблицы, но не самой таблицей. У каждой таблицы может быть сколько угодно
представлений и для всех этих представлений таблица является источником
полей и строк.
Объекты DataView могут быть созданы двумя способами. Первый способ
представляет собой свойство DefaultView непосредственно таблицы-источника.
Предположим, нам нужно создать представление для таблицы Employees базы
данных EmployeeInfo, причем сотрудники в этом представлении должны быть
упорядочены по номеру отдела и получать заработную плату более 10000 рублей.
Для этого нужно использовать следующий код:
dsEmployees.Tables("Employees").DefaultView.RowFilter="Salary >
10000"
dsEmployees.Tables("Employees").DefaultView.Sort="DepartmentID"
Если необходимо отобразить в представлении текущие значения только тех
записей, которые были изменены (но еще не сохранены), то можно изменить
настройки представления:
dsEmployees.Tables("Employees").DefaultView.RowFilter="
"
dsEmployees.Tables("Employees").DefaultView.RowStateFilter=
DefaultView.RowState.ModifiedCurrent
Второй способ создания представления для таблицы представляет собой явное
создание объекта класса DataView для конкретной таблицы с последующей
настройкой свойств (RowFilter, Sort и RowStateFilter) объекта.
dvView2
=
DataView(dsEmployees.Tables("Employees"),
"FirstName", DataViewRowState.CurrentRows)
New
"",
Этой кодовой строкой было создано представление для таблицы Employees, в
котором нет фильтра, сортировка по полю FirstName и изображены текущие
записи таблицы.
Это представление можно изменять, например, установить фильтрацию и
сортировку по убыванию:
dvView2.RowFilter="FirstName
>
'Г'"
dvView2.Sort=
"FirstName
DESC"
dvView2.RowStateFilter=DataViewRowState.Current
Объект DataView имеет модель редактирования, аналогичную модели
редактирования объекта DataTable,. то есть в представлении можно удалять,
добавлять,
редактировать
данные.
Рассмотрим теперь, как описанные выше идеи применяются на практике.
1. Создайте в вашем проекте еще одну форму DataView (рис. 3.5).
2. Добавьте в форме сетку данных DataGrid, текстовой поле с надписью Filter,
поле со списком Sort by Column, поле со списком Row State, флажок Descending и
командную
кнопку
Apply.
3. Выберите все установленные элементы и скопируйте их в форму еще раз.
Обратите
внимание
на
номера
элементов
управления.
4. Скопируйте код, приведенный ниже в ваш проект. Внесите в него изменения в
соответствии с названиями полей таблицы и элементов управления из вашего
проекта.
5. Окончательный вид формы DataView показан на рис. 3.5.
Imports
System.Data
Imports
System.Data.SqlClient
Private
dsEmployees
As
New
DataSet
Private
dvView2
As
DataView
Private Sub Form1_Load(ByVal sender As Object, ByVal e As
System.EventArgs)
Handles
MyBase.Load
Dim
i
As
Integer,
col
As
DataColumn
Dim daEmployees As SqlDataAdapter = New SqlDataAdapter("SELECT
*
FROM
Employees",
"Persist
Security
Info=False; Integrated Security=SSPI; database=EmployeeInfo;
server=abrzh")
'Инициализация
объекта
DataAdapter
daEmployees.Fill(dsEmployees,
"Employees")
'Вставка
данных
только
в
одну
таблицу
dvView2 = New DataView(dsEmployees.Tables("Employees"), "",
"FirstName",
DataViewRowState.CurrentRows)
'Создание
объекта
DataView
'Вставка
списка
имен
полей
в
элементы
ComboBox
For
Each
col
In
dsEmployees.Tables("Employees").Columns
ComboBox1.Items.Add(col.ColumnName)
ComboBox4.Items.Add(col.ColumnName)
Next
'Вставка всех возможных состояний объекта DataViewRowState
Dim
names
As
String()
names
=
DataViewRowState.None.GetNames(DataViewRowState.None.GetType)
For
i
=
0
To
names.GetUpperBound(0)
ComboBox2.Items.Add(names(i))
ComboBox3.Items.Add(names(i))
Next
'Указание
значений
по
умолчанию
TextBox1.Text
=
""
TextBox2.Text
=
""
ComboBox1.SelectedItem
=
"FirstName"
ComboBox4.SelectedItem
=
"FirstName"
CheckBox1.Checked
=
False
CheckBox2.Checked
=
False
ComboBox2.SelectedItem
=
"CurrentRows"
ComboBox3.SelectedItem
=
"CurrentRows"
dsEmployees.Tables("Employees").DefaultView.Sort = "FirstName"
dvView2.Sort
=
"FirstName"
'Связывание
сеток
данных
с
таблицей
DataGrid1.DataSource
=
dsEmployees.Tables("Employees").DefaultView
DataGrid2.DataSource
=
dvView2
End
Sub
Обработка
нажатия
верхней
кнопки
Apply
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs)
Handles
Button1.Click
Dim
sort
As
String
Dim
rowState
As
DataViewRowState
'Указание
фильтра
dsEmployees.Tables("Employees").DefaultView.RowFilter
=
TextBox1.Text
'Указание
сортировки
sort
=
ComboBox1.SelectedItem
If
CheckBox1.Checked
Then
sort
=
sort
&
"
DESC"
End
If
dsEmployees.Tables("Employees").DefaultView.Sort
=
sort
'Указание
состояния
записи
dsEmployees.Tables("Employees").DefaultView.RowStateFilter
=
rowState.Parse(rowState.GetType,
ComboBox2.SelectedItem)
End
Sub
Обработка
нажатия
нижней
кнопки
Apply
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs)
Handles
Button2.Click
Dim
sort
As
String
Dim
rowState
As
DataViewRowState
'Указание
фильтра
dvView2.RowFilter
=
TextBox2.Text
'Указание
сортировки
sort
=
ComboBox4.SelectedItem
If
CheckBox2.Checked
Then
sort
=
sort
&
"
DESC"
End
If
dvView2.Sort
=
sort
'Указание
состояния
записи
dvView2.RowStateFilter
ComboBox3.SelectedItem)
End Sub
=
rowState.Parse(rowState.GetType,
Рис. 3.5. Интерфейс, построенный с использованием объектов DataView
Самостоятельно
1. Скомпонуйте проект DataView и запустите полученное приложение.
Внесите необходимые изменения в критерии сетки и щелкните на кнопке
Apply для внесения этих изменений в соответствующую сетку.
2. Попробуйте выбрать разные поля сортировки и состояния записей для
организации
разных
представлений.
3. Попробуйте использовать разные фильтры, например сложные
выражения Salary>10000 AND Salary<20000 или FirstName Like А.
4. Сетки автоматически поддерживают операции вставки, изменения и
удаления записей, поэтому попробуйте отредактировать записи и
выбрать
соответствующее
состояние
для
отображения
только
измененных записей.
Обратите внимание, как разные представления одной таблицы данных
отображаются в сетках данных. Если вставить, изменить или удалить запись в
одном представлении (и применить изменение за счет перехода к следующей
записи), то внесенные изменения будут автоматически отображены в другом
представлении (если, конечно, эта запись соответствует заданному фильтру).
Задание 4. Привязка данных в формах Windows
Цель
Использовать элементы управления Windows-формы для отображения данных
из таблиц набора данных DataSet.
Решение
Использовать свойства элементов управления Windows-форм для связывания с
элементами данных объекта DataSet.
Обсуждение
В проектах, построенных на основе Windows-форм, используют простую (simple
data binding) и составную (complex data binding) привязки данных.
Простой привязкой данных (simple data binding) называется связывание
элемента управления с единственным элементом данных. Примером такой
привязки данных могут послужить элементы управления TextBox либо Label,
связанные с единственным значением, извлеченным из объекта DataSet либо
источников данных. Для демонстрации техники простой привязки данных к
элементам управления формы рассмотрим связывание текстовых полей TextBox с
элементами данных объекта DataSet. Для примера воспользуемся информацией из
таблицы Employees базы данных EmployeeInfo, с которой мы работаем в текущем
практикуме.
Создайте в проекте еще одну Windows-форму. Разместите в ней 4 надписи, 4
текстовых поля и 2 командные кнопки. Пример такой формы показан на рис. 3.6.
Рис. 3.6. Простая привязка данных к элементам формы
1. Добавьте модуль класса в этот же проект. Класс будем использовать для
разработки общего метода подключения к базе данных и заполнения DataSet.
Класс позволит нам повторное использование метода подключения из других
форм приложения. Код класса приведен ниже.
Imports
System.Data
Imports
System.Data.SqlClient
Public
Class
clsCommon
Public Function PopulateDataSet(ByVal strSQL As
String)
As
DataSet
'Заполним объект DataSet на основе переданного
оператора
SQL
Dim
dsResults
As
New
DataSet
Dim strConnection As String = "Persist Security
Info=False;Integrated
Security=SSPI;database=EmployeeInfo;server=abrzh"
Dim cnn
As
New
SqlConnection(strConnection)
Dim da As New SqlDataAdapter(strSQL, cnn)
cnn.Open()
da.Fill(dsResults)
cnn.Close()
PopulateDataSet
=
dsResults
End
Function
End Class
2. Добавьте следующий программный код в обработчик события
Form1_Load:
Imports
System.Data
Imports
System.Data.SqlClient
Dim
dsEmployees
As
New
DataSet
Private Sub Form7_Load(ByVal sender As Object, ByVal
e As System.EventArgs) Handles MyBase.Load
3. 'Объявим новый экземпляр класса
Dim cCommon As New clsCommon 'вызовем функцию
PopulateDataSet класса clsCommon и передадим ей в
качестве
параметра
оператор
SQL,
'предназначенный
для
извлечения
данных
dsEmployees = cCommon.PopulateDataSet("SELECT
FirstName, LastName, DepartmentId, Salary FROM
Employees")
'свяжем свойство Text текстового поля для FirstName
с
полем
FirstName
таблицы
Employees
TextBox1.DataBindings.Add("Text",
dsEmployees.Tables(0),
"FirstName")
'свяжем свойство Text текстового поля для LastName
с
полем
LastName
таблицы
Employees
TextBox2.DataBindings.Add("Text",
dsEmployees.Tables(0),
"LastName")
'свяжем свойство Text текстового поля для
DepartmentID с полем DepartmentID таблицы
Employees
TextBox3.DataBindings.Add("Text",
dsEmployees.Tables(0), "DepartmentID")
4. Свяжем свойство Text текстового поля для Salary с полем Salary таблицы
Employees
TextBox4.DataBindings.Add("Text",
dsEmployees.Tables(0), "Salary") End Sub
5. Опишите обработчики щелчков по кнопкам, следующим программным кодом:
Private
Sub
Button1_Click(ByVal
sender
As
System.Object, ByVal e As System.EventArgs) Handles
Button1.Click
Me.BindingContext(dsEmployees.Tables(0)).Position -=
1
End
Sub
Private
Sub
Button2_Click(ByVal
sender
As
System.Object, ByVal e As System.EventArgs) Handles
Button2.Click
Me.BindingContext(dsEmployees.Tables(0)).Position
+=
1
End Sub
Составная привязка данных (complex data binding) используется при
связывании элемента управления сразу с несколькими элементами данных, к
примеру, это касается связывания таких элементов управления, как DataGrid с
объектом DataSet в целом. Другим примером составной привязки данных может
послужить связывание элемента управления "комбинированный список"
(ComboBox) с несколькими полями на источнике данных, например, с полем,
отображаемым для пользователя, и со скрытым значением, используемым при
операции обновления записи в самой базе данных.
6. Добавьте в приложение еще одну форму, расположите на ней элемент
ComboBox, сетку DataGrid и командную кнопку (рис. 3.7). Добавьте следующий
фрагмент программного кода для обработки события Form_Load, в рамках
которого будет осуществляться загрузка DataSet и привязка его таблиц к
элементам ComboBox и DataGrid.
Imports
System.Data,
System.Data.SqlClient
Dim
dsDepartment
As
New
DataSet
Dim
dvEmployees
As
New
DataView
Private Sub Form8_Load(ByVal sender As Object, ByVal
e As System.EventArgs) Handles MyBase.Load
7. 'Зададим оператор SQL для извлечения информации из базы данных
Dim strSQL As String = "SELECT ID, DepartmentName
FROM Departments"
8. 'Объявим новый экземпляр класса clsCommon
Dim
cCommon
As
New
clsCommon
'Заполним
DataSet
dsDepartment = cCommon.PopulateDataSet(strSQL)
9. 'Зададим для ComboBox1 в качестве источника данных таблицу из DataSet
ComboBox1.DataSource = dsDepartment.Tables(0)
10. 'Установим для свойства ValueMember объекта ComboBox1 значение ID
ComboBox1.ValueMember
dsDepartment.Tables(0).Columns("ID").ToString
=
11. 'Установим для свойства DisplayMember объекта ComboBox1 значение
DepartmentName
'Эта информация будет выводиться для пользователя
ComboBox1.DisplayMember
=
dsDepartment.Tables(0).Columns("DepartmentName").ToString
12. 'Зададим оператор SQL для извлечения информации из базы данных
strSQL
=
"SELECT
FirstName,
DepartmentID,
Salary
FROM
cCommon = New clsCommon
lastName,
Employees"
13. 'Заполним DataSet
dsDepartment = cCommon.PopulateDataSet(strSQL)
'Создадим представление для таблицы Employees из
DataSet
dvEmployees.Table = dsDepartment.Tables("Table
14. 'Настроим представление на изображение только тех записей таблицы,
которые совпадают с ключом выбранной записи в списке ComboBox1
dvEmployees.RowFilter
=
"DepartmentID="
&
ComboBox1.SelectedValue
'Выведем отфильтрованное представление в сетку
DataGrid1.DataSource
=
dvEmployees
End Sub
15. Добавим программный код для кнопки, позволяющий просматривать записи
только о тех сотрудниках, которые относятся к выбранному отделу.
Private
Sub
Button1_Click(ByVal
sender
As
System.Object, ByVal e As System.EventArgs) Handles
Button1.Click
dvEmployees.RowFilter
=
"DepartmentID="
&
ComboBox1.SelectedValue
End Sub
Рис. 3.7. Составная привязка данных к элементам формы
Самостоятельно
Добавьте в форму Complex data binding кнопку для внесения записей в базу
данных. В класс clsCommom добавьте метод, позволяющий фиксировать
изменения из Dataset в базе данных. Напишите программный код для кнопки
"Внести изменения в базу данных". Метод класса clsCommon для внесения
изменений в базу данных может выглядеть следующим образом:
'строку
strConnection
вынесите
выше
Dim strConnection As String = "Persist Security
Info=False;Integrated
Security=SSPI;database=EmployeeInfo;server=abrzh"
Public
Function
UpdateDBFromDataSet(ByVal
dsChanges As DataSet, ByVal strSQL As String) As
Boolean
Dim cnn
As
New
SqlConnection(strConnection)
Dim da As New SqlDataAdapter(strSQL, cnn)
Dim
cb
As
New
SqlCommandBuilder(da)
cnn.Open()
da.Update(dsChanges)
UpdateDBFromDataSet
=
True
cnn.Close()
End Function
Вызов метода по щелчку на кнопке может иметь следующий вид:
Private
Sub
Button2_Click(ByVal
sender
As
System.Object, ByVal e As System.EventArgs) Handles
Button2.Click
If
Not
dsDepartment.HasChanges(DataRowState.Modified)
Then
Exit
Sub
Dim
changesDataSet
As
DataSet
changesDataSet
=
dsDepartment.GetChanges(DataRowState.Modified)
Dim strSQL As String = "SELECT FirstName, lastName,
DepartmentID,
Salary
FROM
Employees"
Dim
cCommon
As
New
clsCommon
cCommon.UpdateDBFromDataSet(changesDataSet,
strSQL)
End Sub
Скомпонуйте проект и протестируйте его в различных режимах: добавления,
изменения и удаления записей.
Download