| « Поставить закладку » « Сделать стартовой » | |||
|
|||
|
Глава 11. Поддержка баз данных в VB .NET
Глава №11. Поддержка баз данных B VB.NET Столь короткая
глава была написана с единственной целью — ориентировать читателя в нужном
направлении. Ее ограниченный объем не позволит нам даже в общих чертах
представить все средства для работы с базами данных в VB .NET (не говоря
уже об их содержательном обсуждении).
В каждой из
предыдущих версий VB появлялась новая модель поддержки баз данных. VB .NET
следует этой давней традиции и представляет новый способ работы с данными — ADO
.NET. При ближайшем рассмотрении выясняется, что название выбрано крайне
неудачно. Почему? Потому что ADO .NET просто не является следующим поколением
ADO! Это совершенно новая модель, не имеющая ничего общего с классическим
вариантом ADO. В частности, для работы с результатами вам придется освоить новую
объектную модель, основанную на объекте DataSet (объект ADO .NET DataSet не
привязан к одной таблице и поэтому обладает значительно большими возможностями,
чем, например, объект ADO RecordSet). Кроме того, модель ADO
.NET:
Еще одна
интересная особенность ADO .NET заключается в том, что для таких важных средств,
как двухфазная актуализация данных (commit), потребуется использовать Enterprise
Services (то есть фактически COM+/MTS с .NET-оболочкой). Автономные наборы данных: новый подход к работе с базами
данных В VB6 типичное
приложение, использовавшее базы данных, открывало соединение с базой и
использовало его для всех запросов на протяжении жизненного цикла программы. В
VB .NET доступ к базам данных средствами ADO .NET обычно основан на
автономных (отсоединенных) операциях. За этим высокопарным выражением
кроется простой смысл: в большинстве случаев после выборки данных из базы
соединение разрывается. В ADO .NET постоянная связь с источником данных
встречается очень редко (при желании вы можете использовать постоянные
соединения классической модели ADO, прибегнув к услугам .NET COM Interop, однако
при этом неизбежно возникают проблемы масштабируемости, издавна присущие
ADO). Поскольку
программа обычно работает с автономными данными, типичному приложению .NET для
обработки каждого запроса приходится заново подключаться к базе данных. На
первый взгляд это кажется большим шагом назад, но такое впечатление обманчиво.
Старый способ поддержания соединений плохо подходит для мира распределенных
систем: если ваше приложение открывает соединение с базой данных и оставляет
его открытым, серверу приходится поддерживать это соединение до тех пор,
пока клиент его не закроет. Учитывая интенсивную загрузку современных серверов и
пересылку огромных объемов данных, поддержание всех клиентских соединений
отрицательно сказывается на пропускной способности сервера. Кроме того, в
web-комплексах [ Web-комплексом называется группа компьютеров, обрабатывающих
трафик одного URL. Большинство крупных сайтов обслуживается web-комплексами,
обеспечивающими более эффективное распределение нагрузки.](Web farm) запросы
могут обрабатываться разными компьютерами. Постоянные соединения с
web-комплексами бесполезны, поскольку вы не знаете, какой сервер будет
обрабатывать последующие запросы. Сборка System.Data.DLL содержит большое количество классов, разделенных на пять пространств имен работы с данными с дополнительным пространством System.Xml.
Вспомогательное пространство System.Data.SqlTypes содержит структурные типы,
соответствующие типам данных SQL Server (например, Sql Money и
SqlDateTime).
Другое
вспомогательное пространство имен, System.Data .Common, содержит классы, часто
используемые при обращениях к источнику данных. В этой главе основное внимание
уделяется пространствам имен System. Data.OleDb и System. Data. SqlCLient,
выполняющим непосредственную работу. Классы этих пространств имен используют
средства System. Data. Common, включая класс DataAdapter. Класс DataAdapter
представляет соединение с базой данных, используемое при заполнении набора
данных или обновлении источника, а также некоторые стандартные команды при
операциях с базами данных.
Пространство имен System.Data.OleDb Пространство
имен System.Data.OleDb содержит классы, используемые при взаимодействии с OLE
DB-совместимыми базами данных (такими, как Microsoft Access или Microsoft Fox
Pro). Обычно в программах используются классы OleDbConnectl on, OleDbCommand и
OleDbDataReader этого пространства имен. Ниже приведены краткие описания этих
важных классов.
Ниже приведен
пример использования этих трех классов. Наше приложение подключается к базе
данных Northwind, входящей в поставку Access и современных версий SQL
Server. 1 Imports
System.Data.OleDb 2 Module
Modulel 3 Sub
Maint) 4 Dim myAccessConn
As OleDbConnection 5 Dim dbReader As
OleDbDataReader 6 Dim dbCmd As
OleDbCommand =New OleDbCommand( 7 "SELECT
Employees.FirstName.Employees.LastName FROM Employees") 8
Try 9 ' Открыть
соединение 10 myAccessConn =
New OleDbConnection( 11
"Provider=Microsoft.Jet.OLEDB.4.0;" &_ 12 "Data Source=C:Program Files Microsoft _ Office fficeSamplesNNorthwind.mdb") 13
myAccessConn.Open() 14 dbCmd.Connection
= myAccessConn 15 dbReader =
dbCmd.ExecuteReader(CommandBehavior.SingleResult) 16 Do While
dbReader.Read() 17 Console.WriteLine(dbReader.GetString(0) & " " & _ dbReader.GetString(1)) 18
Loop 19
Console.ReadLine() 20 Catch e As
Exception 21
MsgBox(e.Message) 22 End
Try 23 End
Sub 24 End
Module Результаты,
полученные при запуске этого приложения, показаны на рис. 11.1.
Рис. 11.1.
Результаты выполнения простого запроса SQL Хотя наше
приложение всего лишь выводит список работников Northwind, его код типичен для
подключения к любой базе данных при помощи .NET-провайдера OLE DB,
предоставленного VB .NET. В строке 1 для упрощения дальнейших ссылок
импортируется пространство имен System. Data. 0leDb. В строках 4 и 5 объявляются
две объектные переменные. Объект 0leDbConnecti on инкапсулирует текущее
соединение к провайдеру OLE DB и в конечном счете к базе данных (строки 10-12).
Объект 0leDbDataReader инкапсулирует рабочие данные. В отличие от объектов
RecordSet эти данные не обязаны относиться к одной таблице (хотя в нашем примере
это именно так). Строка 6 определяет запрос SQL, хранящийся в объекте
OleDbCommand. Использована версия конструктора с параметром типа Stri ng, в
котором передается команда SQL, — в нашем случае это простейший из всех
возможных запросов. В строке 10 создается соединение с базой данных. При вызове
конструктора передается строка с именем провайдера OLE DB. Значение берется из
реестра Windows и не является частью .NET (в нашем примере используется
стандартный провайдер для Access). Также обратите внимание на жесткую кодировку
местонахождения базы данных Northwind; в нашем примере выбран каталог,
используемый по умолчанию при установке Office. Если на вашем компьютере база
данных Northwind находится в другом каталоге, отредактируйте эту
строку. Затем созданное
соединение открывается. Поскольку эта операция по различным причинам может
завершиться неудачей, программный код открытия и чтения из базы данных
заключается в блок Try-Catch. После успешного вызова Ореn() (строка 13)
соединение можно использовать в программе (выполнение этих операций в
конструкторе позволило бы сократить программу на несколько строк). Объект
OleDbCommand пока не знает, какое соединение он должен использовать, поэтому
открытое соединение с базой данных назначается свойству Connecti on объекта
OleDbCommand (строка 14). Одно из преимуществ подобного решения заключается в
том, что оно позволяет использовать один объект команды с несколькими
соединениями. Команда
выполняется методом ExecuteReader() объекта 0leDbCommand (строка 15). Мы
используем метод ExecuteReader, поскольку остальные методы Execute возвращают
данные в формате XML и традиционные наборы записей, обрабатываемые менее
эффективно. В строке 14 значение перечисляемого типа CommandBehavior.
SingleResul t передается методу ExecuteReader в качестве параметра. Флаг Si ngl
eResult означает, что команда должна выбрать из базы данных все записи
результата. Другие флаги позволяют ограничить выборку одной или несколькими
записями. Прочитанные записи перебираются в цикле в строках
16-18. Код перебора
записей эквивалентен следующему фрагменту VB6/ADO: Do While Not
rs.EOF Print
rs(0) rs.MoveNext()
Loop Использование
метода Read предотвращает одну распространенную ошибку, часто допускаемую
программистами VB6 ADO, которые забывают перейти к следующей записи методом
MoveNext. Все операции с одной записью выполняются между вызовами Read,
поскольку после вызова Read вернуться к содержимому предыдущей записи уже не
удастся. В цикле
вызываются различные методы GetXXX объекта 01 eDbReader, возвращающие значение
поля с заданным индексом (нумерация полей записи начинается с 0). Таким образом,
вызов dbReader.GetString() возвращает
значение второго столбца в формате String. Вместо индекса при вызове
GetStrlng можно указать имя столбца, но этот вариант менее
эффективен.
Чтение данных из
базы SQL Server происходит аналогичным образом — пространства имен OleDb и
SqlClient имеют практически одинаковый синтаксис. Ниже приведена версия
предыдущей программы для SQL Server: Imports System.Data.SqlClient Module
Modulel Sub
Main() Dim mySQLConnString
As String Dim mySQLConn As
SqlConnection Dim dbReader As
SqlDataReader Dim dbCmd As
SqlCommand = New SqlCommand( "SELECT
Employees.FirstName.Employees.LastName FROM Employees")
Try mySQLConnString =
_ "uid-test:password=apress; database=northwind:server=Apress" mySQLConn = New
SqlConnection(mySQLConnString) mySQLConn.Open() dbCmd.Connection =
mySQLConn dbReader =
dbCmd.ExecuteReader(CommandBehavior.SingleResult) Do While
dbReader.Read() ' Вывести данные в консольном окне Console.WriteLinetdbReader.GetString(0) & "." &_ dbReader.GetString(1)) Loop Catch e As Exception MsgBox(e.Message) End
Try Console. ReadLine() End Sub End
Module Основное
различие (помимо имен классов) наблюдается в формате строки соединения.
Предполагается, что на сервере Apress имеется учетная запись с паролем apress.
При подключении к SQL Server в строке соединения указывается идентификатор
пользователя, пароль, сервер и имя базы данных. Передавая эту информацию, мы
получаем объект соединения. Конечно, лишь простейшие запросы формулируются в
виде простой строки; в любом сколько-нибудь нетривиальном случае строку запроса
приходится строить из отдельных фрагментов.
"execute getalbumbyname 'Operation Mindcrime'") Try "database=albums;server=i-ri3")
End Try
Нетривиальный пример работы с базами данных в VB .NET
Рис. 11.2.
Главная форма приложения
Рис. 11.3.
Форма результатов приложения 'frmMain.vb Imports
System.Data.SqlClient Public Class
frmMain Inherits System.Windows.Forms.Form #Region "Windows Form Designer generated code " Public Sub New() MyBase.New() 'Вызов необходим для работы дизайнера форм Windows InitializeComponent() ' Дальнейшая инициализация выполняется ' после вызова InitializeComponent() End
Sub ' Форма переопределяет Dispose для очистки списка компонентов. Protected Overloads Overrides Sub Dispose(ByVal disposing As
Boolean) If Disposing
Then If Not (components
Is Nothing) Then components. Dispose() End
If End
If MyBase.Dispose(Disposing) End Sub Private WithEvents Label1 As System.Windows.Forms.Label Private WithEvents Label2 As System.Windows.Forms.Label Private WithEvents Label3 As System.Windows.Forms.Label Private WithEvents Label4 As System.Windows.Forms.Label Private WithEvents btnConnect As System.Windows.Forms.Button Private WithEvents txtUID As System.Windows.Forms.TextBox Private WithEvents txtPassword As System.Windows.Forms.TextBox Private WithEvents txtDatabase As System.Windows.Forms.TextBox Private WithEvents txtServer As System.Windows.Forms.TextBox ' Необходимо для работы дизайнера форм Windows Private components As System.ComponentModel.Container ' ВНИМАНИЕ: следующий фрагмент необходим для дизайнера форм Windows ' Для его модификации следует использовать дизайнер форм. ' Не изменяйте его
в редакторе! <System.Diagnostics.DebuggerStepThrough()> Private Sub _
Initial izeComponent() Me.Label4 = New
System.Windows.Forms.Label () Me.txtPassword =
New System.Windows.Forms.TextBox() Me.Label 1 = New
System.Windows.Forms.Label () Me.txtServer = New
System.Windows.Forms.TextBox() Me.Label2 = New
System.Windows.Forms.Label () Me.Labels = New
System.Windows.Forms.Label () Me.txtUID - New
System.Windows.Forms.TextBox() Me.txtDatabase =
New System.Windows.Forms.TextBox() Me.btnConnect = New
System.Windows.forms.Button() Me.SuspendLayout() 'Label4 Me.Label4.Location
= New System.Drawing.Point(24.176) Me.Label 4.Name =
"Label4" Me.Label4.Size =
New System.Drawing.Size(82.19) Me.Label4.TabIndex
= 0 Me.Label4.Text =
"Password:" Me.Label4.TextAlign
= System.Drawi ng.ContentAlignment.MiddleRight 'txtPassword Me.txtPassword.Location = New
System.Drawing.Point(168.168) Me ..txtPassword.
Name = "txtPassword" Me.txtPassword.PasswordChar = ChrW(42) Me.txtPassword.Size
= New System.Drawing.Size(205.22) Me.txtPassword.Tablndex = 3 Me.txtPassword.Text
= "" 'Label
1 Me.Label 1.Location
= New System.Drawing.Point(24. 32) Me.Label 1.Name =
"Label1" Me.Label 1.Size =
New System.Drawing.SizeC82. 20) Me.Label 1.Tablndex
=0 Me.Label 1.Text =
"Server:" Me.Label 1.TextAli
gn = System.Drawi ng.ContentAlignment.Mi ddleRight 'txtServer Me.txtServer.Location - New System.Drawing.Point(168, 24} Me.txtServer.Name =
"txtServer" Me.txtServer.Size =
New System.Drawing.Size(205. 22) Me.txtServer.Tablndex = 0 Me.txtServer.Text =
"" 'Label
2 Me.Label2.Location
= New System.Drawing.Point(24. 80) Me.Label 2.Name =
"Label 2" Me.Label2.Size =
New System.Drawing.Size(82, 20) Me.Label2.Tablndex
= 0 Me.Label 2.Text =
"Database:" Me.Label
2.TextAlign = System.Drawi ng.ContentAlignment.Mi ddleRight 'Label3 Me. Labels.Anchor =
System.Windows.Forms.AnchorStyles.None Me.Label3.Location
= New System.Drawing.Point(24. 128) Me.Labels.Name =
"Label 3" Me.Labels.Size =
New System.Drawing.Size(82. 20) Me.Labels.Tablndex
= 0 Me.Labels.Text =
"User ID:" Me.Label 3.TextAli
gn = System.Drawi ng.ContentAlignment.Mi ddleRi ght 'txtUID Me.txtUID.Location
= New System.Drawing.Point(168, 120) Me.txtUID.Name =
"txtUID" Me.txtUID.Size -
New System.Drawing.Size(205, 22) Me.txtUID.Tablndex
= 2 Me.txtUID.Text =
"" 'txtDatabase Me.txtDatabase.Location = New System.Drawing.Point(168.
72) Me.txtDatabase.Name
= "txtDatabase" Me.txtDatabase.Size
= New System.Drawing.Size(205. 22) Me.txtDatabase.Tablndex = 1 Me.txtDatabase.Text
= "" 'btnConnect Me.btnConnect.Location = New System.Drawing.Point(160.
232) Me.btnConnect.Name
= "btnConnect" Me.btnConnect.Size
= New System.Drawing.Size(92, 30) Me.btnConnect.Tablndex = 4 Me. btnConnect.Text
= "SConnect" 'frmMain Me.AutoScaleBaseSize = New System.Drawing.Size(6. 15) Me.ClientSize - New System.Drawing.Size(408, 280) Me.Controls.AddRange(New _ System.Wi
ndows.Forms.Control(){Me.btnConnect,_ Me.txtPassword.
Me.txtUID. Me.txtDatabase. Me.txtServer.Me .Label 4. Me.Label3.Me .Label 2. Me.Label 1}) Me.Name - "frmMain" Me.Text = "DB Connector" Me.ResumeLayout(False) End Sub #End
Region Private Sub btnConnect_C1ick(ByVal sender As System.Object,_ ByVal e As System.EventArgs) Handles btnConnect.Click Try mySQLConn = New SqlConnectionC'user id=" & txtUID.Text & ";password="&txtPassword.Text & _ ";database="&txtDatabase.Text & _ ";server="&txtServer.Text) mySQLConn.Open() dbCmd.Connect!on = mySQLConn Dim frmChild As New frmResults() frmChild.Show() Catch except As
Exception MsgBox(_ "Failed to connect for the following reason:<" & _ except.Message & ">") End Try End Sub End
Class Модуль содержит
следующий код: Imports
System.Data.SqlClient Module main ' Глобальные
определения Public mySQLConn As
SqlConnection Public dbReader As
SqlDataReader Public dbCmd As SqlCommand = New SqlCommand() End
Module
Вероятно,
наибольший интерес представляет форма 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. За подробностями
обращайтесь к специализированной литературе. HTML 5: пять вещей вызывающих особый интер....
HTML 5 — это грядущее обновление гипертекстового языка разметки, основного способа создания контента для размещения его во всемирной паутине. Разработка HTML остановилась в 1999 году, на версии HTML 4.01 и с тех пор web-содержимое изменилось так, что текущие спецификации HTML перестали соответствовать сегодняшним требованиям. HTML 5 нацелен на то, чтобы увеличить функциональную совместимость HTML и соответствовать растущим требованиям разнообразного и смешанного web-контента. HTML 5 так же нацелен на устранение недостатков четвертой версии. В этой статье мы взглянем на 5 новых интересных вещей в HTML 5.
Подробнее... |
Рубрика: Html
| Добавлено: 22.12.2008
asp.net: ListView с разных сторон.
Элемент управления ListView был представлен в .Net Framework 3.5 как замена устаревшему GridView. Новый элемент имеет более расширенный функционал, чем его предшественник, но в тоже время лишен некоторых внутренних механизмов, что впрочем целиком следствие из расширенной универсальности ListView. Среди отличий ListView и GridView можно назвать и гибкую настройку разметки, что позволяет выводить данные не только в табличном виде, но и вообще в любом каком пожелает программист. Благодаря шаблонам ItemTemplate, EditItemTemplate, InsertItemTeplate можно настроить внешний вид при любом из состояний ListView: редактировании или выборе элемента.
Подробнее... |
Рубрика: .NET компоненты
| Добавлено: 22.12.2008
Создание кросс-таб отчета в Stimulsoft Rep....
Компания Стимулсофт предоставляет для разработчиков мощный набор инструментов для создания отчетов для Microsoft Visual Studio .Net 2005 и 2008; эти инструменты доступны как для Windows Forms, так и для Web Forms. Это генератор отчетов Stimulsoft Reports.Net. Генератор отчетов Stimulsoft Reports.Net имеет ряд особенностей: простая работа с дизайнером отчетов, полная поддержка экспорта в PDF, Word, Excel и многие другие форматы. Crystal Report и Microsoft Reporting Service – очень хорошие программные продукты для повседневной работы, но, если Вам необходимо создать отчеты с поддержкой кросс-табов, drill down, Ajax, штрих-кодов и возможностью подключения одновременно более одного источника данных, то Stimulsoft Reports.Net поможет Вам сэкономить массу времени. Также, данный генератор отчетов позволяет пользователям создавать свои собственные отчеты любой сложности. И все эти особенности делают Stimulsoft Reports.Net хорошим выбором в сфере программных продуктов для Business Intelligence.
Подробнее... |
Рубрика: .NET компоненты
| Добавлено: 22.12.2008
Остальные статьи: |
Цитата дня (все,добавить):
|
Realcoding.NET
© 2003-2008 |
Контакты |
Реклама на сайте
|