|
|||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||
|
Нетривіальний
приклад роботи з базами даних в VB .NET
(частина 2)
Ймовірно,
найбільший інтерес представляє
форма frmresults (коментарі слідують
після лістингу). Ключове місце в
цій формі займає метод btnquery_click,
виділений жирним шрифтом: ' frmresults.vb Imports System.Data.SqlClient Public
Class frmresults Inherits System.Windows.Forms.Form fregion "Windows Form Designer generated code " Public Sub New()
Mybase.New() 'Виклик необхідний для роботи дизайнера форм Windows Initializecomponent() ' Подальша ініціалізація виконується ' після виклику Initializecomponent() End
Sub ' Форма перевизначає Dispose для очищення списку компонентів. Public Overrides Sub Dispose() Mybase.Dispose() If Not (components Is Nothing) Then components. Dispose() End If End Sub Private Withevents txtquery As System.Windows.Forms.TextBox Private Withevents btnquery As System.Windows.Forms.Button Private Withevents Istdata As System.Windows.Forms.ListBox ' Необхідно для роботи дизайнера форм Windows Private components As System.ComponentModel.Container ' УВАГА: наступний фрагмент необхідний для дизайнера форм Windows ' Для його модифікації слід використовувати дизайнер форм. ' Не змінюйте його в редакторові! <System.Diagnostics.DebuggerStepThrough()> Private
Sub _ Initial izecomponent() Me.btnQuery = New System.Windows.Forms.Button() Me.txtQuery = New System.Windows.Forms.TextBox() Me.IstData = New System.Windows.Forms.ListBox() Me.SuspendLayout() 'btnquery Me. btnquery. Font = Newsystem. Orawing. Font ("Microsoft Sans Serif"._ 8.5!.system.drawing.fontstyle.regular System.Drawing.GraphicsUnit.Point,CType(0.
Byte)) Me.btnQuery.Location
= New System.Drawing.Point(440. 0) Me.btnQuery.Name =
"btnquery" Me.btnQuery.Size =
New System.Drawing.Size(56. 24) Me.btnQuery.Tablndex
= 2 Me.btnQuery.Text =
"&execute" 'txtquery Me. txtquery. Font=new
System. Drawing. Font ("Microsoft Sans Serif" _ 8.5!. System.Drawing.FontStyle.Regular. System.Drawi ng.Graphi csunit.Point.CTypet 0. Byte)) Me.txtQuery.Location = New System.Drawing.Point(8. 0) Me.txtQuery.Name = "txtquery" Me.txtQuery.Size = New System.Drawing.Size(432, 20) Me.txtQuery.Tablndex = 1 Me.txtQuery.Text =
"Textbox1" 'Istdata Me.lstData.ColumnWidth
= 120 Me.IstData.Location
= New System.Drawing.Point(8. 32) Me.lstData.MultiColumn
= True Me.lstData.Name =
"Istdata" Me.lstData.Size =
New System.Drawing.Size(488. 355) Me.lstData.Tablndex
= 3 'frmresults Me.AutoScaleBaseSize
= New System.Drawing.Size(5. 13) Me.ClientSize = New
System.Drawing.Size(504. 397) Me.Controls.AddRange(New
System.Windows.Forms.Control() {Me.lstOata. Me.btnQuery, Me.txtQuery}) Me.Name = "frmresults" Me.Text = "Query Window" Me.ResumeLayout(False) End Sub #End
Region Private Sub btnquery_click(Byval sender As System.Object, Byval e As System.EventArgs) Handles btnquery.Click Try dbcmd.CommandText =
txtquery.Text dbreader=dbcmd.
Executereader (Coimandbehavior. Singl eresult) '
Отримати схему таблиці Dim dtbllnfo As
Datatable = dbreader.GetSchemaTable() '
Службова змінна для перебору записів Dim
rwrow As Datarow Dim strheaders As
System.Text.StringBuilder - _ New System.Text.StringBuilder() Dim strdata As
System.Text.StringBuilder = New _ System.Text.StringBuilder() Dim typtypescdtbllnfo.Columns.Count) As Type Dim intcounter As Integer = 0 ' Перебрати всі записи метаданих For Each rwrow In dtblinfo.Rows '
Визначити тип typtypes(intcounter)= rwrow("Datatype") intcounter +=1 ' Включити в рядок ім'я поля
strheaders.Append("<" & rwrow(0)& ">" & vbtab) Next ' Занести в список заголовний рядок 1stdata.Items.Add(strheaders.ToString()) ' Перебір записів даних Do While dbreader.Read() '
Перебір полів запису For intcounter = 0 To (dbreader.FieldCount - 1) ' Включити вміст поле у вихідний рядок strdata.Append(Getpropertype(dbreader,intcounter,_ typtypes(intcounter))
& vbtab) Next ' Включити рядок в список 1stdata.Items.Add(strdata.ToString()) ' Очистити об'єкт Stringbuilder strdata = New System.Text.StringBuilder() Loop
Catch except As Exception Msgboxt"error:" & except.Message) End Try End
Sub ' Функція отримує дані конкретного стовпця. Private Function
Getpropertype(Byval dr As Sqldatareader. Byval intpos As Integer, Byval typtype As Type) As Object ' Перевірити тип поля, потім набути значення Select Case typtype.Name
Case "String" ' Перетворити і повернути Return Ctype(dr.GetString(intpos).String) Case
"Int32" ' Перетворити і повернути Return Ctype(dr.Get!nt32(intpos). Int32) ' Тут слід було б організувати перевірку всіх ' решти типів і повернення відповідних значень. ' Ми вибрали простий шлях і обмежилися перевіркою ' двох найпоширеніших типів Case
Else Return "<unsupported Type>" End Select End Function End
Class 'При натисненні кнопки в об'єкт команди SQL 'заноситься
текст, введений користувачем в
текстовому полі: dbcmd.CommandText =
txtquery.Text (у справжньому
прикладі пропущена перевірка даних,
необхідна в будь-якій реальній
програмі). Далі
оголошуються об'єкти, використовувані
при читанні і виведенні імен полів і їх
значень: Dim dtbllnfo As
Datatable = dbreader.GetSchemaTable() Dim
rwrow As Datarow Dim strheaders As
System.Text.StringBuilder = New _ System.Text.StringBuilder() Dim strdata As
System.Text.StringBuilder = New _ System.Text.Stri ngbui1der() Dim typtypes(dtblinfo.Columns.Count)
As Type Оскільки в
цьому застосуванні структура бази
даних не відома заздалегідь, ми
отримуємо її опис за допомогою
методу Getschematable(). Цей метод
повертає об'єкт Datatable з
метаданими (описами полів
записів отриманого набору).
Метадані містять інформацію про
кількість полів в записі, їх
іменах і типах. На підставі цієї
інформації можна запитати і
вивести дані з будь-якої доступної
бази даних. Пам'ятаєте, що в режимі
Option Strict On (який завжди має
бути активним) для виклику
правильної функції GETXXX() об'єкту
Datareader необхідно знати тип поля. З
міркувань ефективності в
приведеному прикладі використані
дві змінні типу Stri ngbui I der (див.
нижчий). Інформація, необхідна для
виведення даних в списку, витягується
в циклі: Dim intcounter As
Integer =0 For Each rwrow In dtbllnfo.Rows typtypes(intcounter)
= rwrow("'datatype") intcounter += 1
strheaders.Append("<" & rwrow(0)& ">" & vbtab) Next Записи Datatable
перебираються в циклі For Each. Типи
полів зберігаються в масиві typtypes і
потім приєднуються до об'єкту
Stringbuilder для подальшого виведення
всіх імен стовпців за одну операцію
(одноразове оновлення властивості
виконується швидше багатократних).
Також звернете увагу на
використання імені поля у виклику
rwrow( "Datatype") — структура
таблиці може змінитися, що
приведе до зміни номера поля
Datatype. Після завершення циклу у нас
з'явиться вся необхідна
інформація про імена і типи всіх
полів, і ми зможемо перейти до її
виводу в конструкції з вкладеним
циклом: Do While dbreader.Read() For intcounter = 0
To (dbreader.FieldCount = 1) strdata.Append(Getpropertype(dbreader.intCounter, typtypes(intcounter))
& vbtab) Next 1stdata.Items.Add(strdata.ToString()) strdata = New System.Text.StrlngBuilder()
Loop Перша частина
циклу нагадує аналогічні
конструкції з попередніх прикладів
— ми перебираємо всі поля запису,
визначуваний тип кожного поля і
виводимо дані в списку перед
наступним викликом Read. Для спрощення
цього завдання була написана
допоміжна функція Getpropertype(). На мал. 11.4
показаний результат вибірки даних
з бази Northwind.
Мал. 11.4. Результат
обробки запиту до бази даних Northwind У цьому розділі ми
постаралися дати уявлення про
роботу з ADO .NET, проте читач
повинен пам'ятати, що перед ним лише
гранично короткий огляд. Зокрема,
ми абсолютно не торкнулися
таких тим, як оновлення даних
в процедурах, що зберігаються,
елементи, пов'язані з даними, або
об'єкти Dataadapter/dataset. За
подробицями звертайтеся до
спеціалізованої літератури.
|
|
|||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||