ADO+ - пара надстроек, илиЕ (Сравнение
ADO+ и ADO)
Программисты,
проработавшие достаточно долго с ADO
вполне могли оценить простоту и
удобство этой технологии. Однако, Microsoft
не ограничилась несколькими новыми
методами, а переделала всю объектную
модель новой технологии.
Большей частью при использовании ADO
сохранялось активным соединение с базой
данных (хотя поддерживается и
однократное подключение с последующей
потерей активного соединения ). Только
это обеспечивало полную
функциональность. ( для объекта Recordset,
например). Предположим, в таком случае
вам необходимо получить данные из некой
(возможно очень даже солидной) таблицы.
Все то время, пока информация
считывается, обрабатывается и т.д.
поддерживается установленное
соединение. Только после вызовов
методов Close() объектов Recordset и Connection (полагаем
их открытыми) соединение будет
разорвано. В ADO+ же акцент ставится на
модель с соединением, не поддерживаемым
все время. В ADO+ вы создаете обект Recordset
УотсоединеннымФ (Disconnected model) по уолчанию.
Таким образом после получения данных
соединение может быть немедленно
разорвано, даже если с данными
необходимо проводить те или иные
операции.
Опрежая ваши возражения,
скажу, что хотя мы могли выполнить все
выше сказанное и с классическим Recordset
Object из ADO, но новый объект, Dataset, был
значительно улучшен и дополнен.
Recordset vs Dataset.
Хотя объект Recorset исчезает в ADO+ , его
переемник, Dataset object, выполняет схожие
функции, а потому и интерфейсы их схожи.
Но, несмотря на внешнюю схожесть,
разница в способе хранения данных очень
существенна. В отличие от Recordset Object, Dataset
Object позволяет сохранять в одном объекте
различные таблицы, их связи, столбцы,строки
и ключи. Более того, поддерживается
программное добавление любого из
вышеперечисленного в объект Dataset.
То есть, в принципе, Dataset
может представлять данные как
реляционная база данных. Перечислим
основные особенности объекта Dataset:
1. Dataset не взаимодействует
непосредственно с источником данных. 2.
Dataset позволяет сохранять связи между
таблицами.
3. Возможно перемещение по таблицам по их
связям.
4. Dataset не использует COM Marshalling для
передачи данных между компонентами. Для
этих целей теперь используется XML.
5. Так как за основу взят XML стала
возможной передача данных между
произвольными (не только COM) объектами.
По крайней мере одно
преимущество Dataset следует прямо из этого
списка: использование COM маршалинга
накладывает ограничения на типы данных
и вызывает конверцию данных при
передаче Disconnected Recordsen. Dataset же свободен
от этих ограничений. XML позволяет
передавать более широкий набор данных, а
использование HTTP позволит пересылать
данные другим компонентам через
брандмауэры используя стандартныуе
порты.
Managed Providers (Managed - очень
модное слово в .NET)
В ADO+ предусмотрены 2
поставщика данных, называемые Managed Providers:
1. SQL Server 7.0 and higher provider (ADO+ SQL ServerManaged Provider)
2. An OLE DB provider - для доступа ко всем
остальным типам данных (ADO+ Managed Provider)
Поставщик данных отвечает за сбор
данных и знает, как взаимодействовать с
базой данных. В то же время Dataset о БД не
знает ничего и его не волнует, откуда
пришли данные и куда пойдут. Поставщик
полностью отвечает за работу с БД,
выполняя выборки, обновления, вставки и
т.д.
Как ясно из названия, при работе с SQL SERVER
7.0 and higher рекомендуется использовать SQL
Server managed provider. Используя специальный
протокол (Tabular Data Stream - TDS), поставщик
предоставляет прямой доступ к БД,
обеспечивая максимальную
поизводительность. Безусловно, возможно
использование и другого поставщика, но
он создан более общим, а потому не может
достичь такого же уровня исполнения.
Если же вы будете
использовать не SQL Server то вам придется
использовать общий поставщик, который
основан на чистом ODBC. Вне зависимости от
того, какой поставщик вы будете
использовать, вам придется работать с
тремя общими объектами для
взаимодействия с БД:
1. Connection Object
2. Command Object
3. DatasetCommand
Connection Object
Следующие примеры кода
иллюстрируют инициализацию соединения
с БД:
using System.Data;
using System.Data.SQL;
public class SQLConnect {
private String connString = "";
private SQLConnection dataConn = null;
public string openConnection(String dbConnectString) {
connString = dbConnectString;
try {
dataConn = new SQLConnection(connString);
dataConn.Open();
return "SQL Server Data Connection Opened";
}
catch (Exception e) {
return(e.ToString());
}
finally {
if (dataConn != null) {
dataConn.Close();
}
}
}
} // End Class
|
ADO+ Provider:
using System.Data;
using System.Data.ADO
public class ADOConnect {
private String connString = "";
private ADOConnection dataConn = null;
public string openConnection(String dbConnectString) {
connString = dbConnectString;
try {
dataConn = new ADOConnection(connString);
dataConn.Open();
return "ADO+ Data Connection Opened";
}
catch (Exception e) {
return(e.ToString());
}
finally {
if (dataConn != null) {
dataConn.Close();
}
}
}
}
|
Command Object
Хотя установка
соединения с БД важна, но нам необходимо
средство для получения данных. Здесь нам
поможет Command object, используемый в ADO+ так
же, как и в ADO
Ниже показаны примеры
использования Command Object для обоих Managed
Providers.
using System.Data;
using System.Data.SQL;
public class SQLConnect {
private SQLConnection dataConn = null;
private SQLDataReader reader = null;
public string openConnection(HttpResponse Response,String
dbConnectString,String cmdString) {
try {
dataConn = new SQLConnection(dbConnectString);
SQLCommand sqlCmd = new SQLCommand(cmdString,dataConn);
dataConn.Open();
sqlCmd.Execute(out reader);
Response.Write("<table><tr><td><b>ID</b></td>");
Response.Write("<td><b>Name</b></td></tr>");
while (reader.Read()) {
Response.Write("<tr>");
Response.Write("<td>" +reader["CategoryID"].ToString());
Response.Write("</td>");
Response.Write("<td>");
Response.Write(reader["CategoryName"].ToString());
Response.Write("</td>");
Response.Write("</tr>");
}
Response.Write("</table>");
return "<p>SQL Server Data Connection Opened";
}
catch (Exception e) {
return(e.ToString());
}
finally {
if (reader != null) {
reader.Close();
}
if (dataConn != null) {
dataConn.Close();
}
}
}
} // End Class
|
ADO+ Provider:
using System.Data;
using System.Data.ADO;
public class ADOConnect {
private ADOConnection dataConn = null;
private ADODataReader reader = null;
public string openConnection(HttpResponse Response,String
dbConnectString,String cmdString) {
try {
dataConn = new ADOConnection(dbConnectString);
ADOCommand adoCmd = new ADOCommand(cmdString,dataConn);
dataConn.Open();
adoCmd.Execute(out reader);
Response.Write("<table><tr><td><b>ID</b></td>");
Response.Write("<td><b>Name</b></td></tr>");
while (reader.Read()) {
Response.Write("<tr>");
Response.Write("<td>");
Response.Write(reader["CategoryID"].ToString());
Response.Write("</td>");
Response.Write("<td>");
Response.Write(reader["CategoryName"].ToString());
Response.Write("</td>");
Response.Write("</tr>");
}
Response.Write("</table>");
return "<p>ADO Server Data Connection Opened";
}
catch (Exception e) {
return(e.ToString());
}
finally {
if (reader != null) {
reader.Close();
}
if (dataConn != null) {
dataConn.Close();
}
}
}
} // End Class
|
Command Object имеет множество
конструкторов, принимающих различные
параметры. В наших примерах мы
передавали строку с SQL скриптом и Connection
Object .
Пара слов о DataReader Object - в
отличие от Dataset он использует forwardonly
доступ и хранит только одну строку в
памяти в каждый момент времени. Так как
он читает построчно, то вынужден
поддерживать соединение (очень похоже
на обычный Recordset).
При инициализации объекта
устанавливаются различные свойства по
умолчанию. Например, поле CommandType
устанавливается в CommandType.Text. Однако
легко можно вызывать и сохраненные
процедуры.
using System.Data;
using System.Data.SQL;
public class SQLConnect {
private SQLConnection dataConn = null;
private SQLDataReader reader = null;
public string openConnection(HttpResponse Response,String
dbConnectString,String cmdString) {
try {
dataConn = new SQLConnection(dbConnectString);
SQLCommand sqlCmd = new SQLCommand(cmdString,dataConn);
sqlCmd.CommandType = CommandType.StoredProcedure;
SQLParameter param = sqlCmd.Parameters.Add(new
SQLParameter("@CustomerID",SQLDataType.Char, 5));
param.Direction = ParameterDirection.Input;
sqlCmd.Parameters["@CustomerID"].Value = "ALFKI";
dataConn.Open();
sqlCmd.Execute(out reader);
Response.Write("<table><tr><td><b>Product Name</b></td>");
Response.Write("<td><b>Total</b></td></tr>");
while (reader.Read()) {
Response.Write("<tr>");
Response.Write("<td>"+reader["ProductName"].ToString());
Response.Write("</td>");
Response.Write("<td>"+reader["Total"].ToString());
Response.Write("</td></tr>");
}
Response.Write("</table>");
return "<p>SQL Server Data Connection Opened";
}
catch (Exception e) {
return(e.ToString());
}
finally {
if (reader != null) {
reader.Close();
}
if (dataConn != null) {
dataConn.Close();
}
}
}
} // End Class
|
ADO+ Provider:
using System.Data;
using System.Data.ADO;
public class ADOConnect {
private ADOConnection dataConn = null;
private ADODataReader reader = null;
public string openConnection(HttpResponse Response,String
dbConnectString,String cmdString) {
try {
dataConn = new ADOConnection(dbConnectString);
ADOCommand adoCmd = new ADOCommand(cmdString,dataConn);
adoCmd.CommandType = CommandType.StoredProcedure;
ADOParameter param = null;
param = adoCmd.Parameters.Add("@CustomerID", ADODBType.Char, 5);
param.Direction = ParameterDirection.Input;
adoCmd.Parameters["@CustomerID"].Value = "ALFKI";
dataConn.Open();
adoCmd.Execute(out reader);
Response.Write("<table><tr><td><b>Product Name</b></td>");
Response.Write("<td><b>Total</b></td></tr>");
while (reader.Read()) {
Response.Write("<tr>");
Response.Write("<td>" + reader["ProductName"].ToString());
Response.Write("</td>");
Response.Write("<td>" + reader["Total"].ToString() + "</td>");
Response.Write("</tr>");
}
Response.Write("</table>");
return "<p>ADO Server Data Connection Opened";
}
catch (Exception e) {
return(e.ToString());
}
finally {
if (reader != null) {
reader.Close();
}
if (dataConn != null) {
dataConn.Close();
}
}
}
} //End Class
|
Код похож на предыдущий
пример, но он выполняет сохраненные
процедуры вместо SQL скрипта. В следующей
статье мы рассмотрим, как получить
данные после выполнения процедуры