Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ADO.NET.doc
Скачиваний:
1
Добавлен:
01.07.2025
Размер:
200.19 Кб
Скачать

Объект DataReader

С помощью ADO.NET DataReader можно получить однопроходный поток данных из базы данных, доступный только для чтения. Результаты возвращаются после выполнения запроса и хранятся в сетевом буфере на клиенте до тех пор, пока не будут запрошены с помощью метода Read.

Объект DataReader предоставляет небуферизованный поток данных, позволяющий процедурам последовательно обрабатывать результаты из источника данных. Объект DataReader хорошо подходит для извлечения больших объемов данных, поскольку данные не кэшируются в памяти. Чтобы создать объект SqlDataReader вместо того, чтобы воспользоваться непосредственно конструктором, рекомендуется вызвать метод ExecuteReader объекта SqlCommand.

SqlDataReader reader = command.ExecuteReader();

Извлечение данных с помощью DataReader

Для извлечения данных с помощью DataReader необходимо создать экземпляр объекта Command, а затем создать объект DataReader, вызвав метод Command.ExecuteReader для получения строк из источника данных.

Свойство HasRows позволяет определить, возвратил ли объект DataReader какие-либо результаты, перед тем как читать из него. Метод Read объекта DataReader используется для получения строки из результатов запроса.

static void function(SqlConnection connection)

{

using (connection)

{

SqlCommand command = new SqlCommand(

"SELECT CategoryID, CategoryName FROM Categories;", connection);

connection.Open(); 

SqlDataReader reader = command.ExecuteReader(); 

if (reader.HasRows)

{

while (reader.Read())

{

Console.WriteLine("{0}\t{1}", reader.GetInt32(0), reader.GetString(1));

}

}

else

{

Console.WriteLine("No rows found.");

}

reader.Close();

}

}

По окончании использования объекта DataReader всегда следует вызывать метод Close. Пока объект DataReader открыт, соединение Connection используется исключительно этим объектом DataReader. Невозможно выполнять какие-либо команды для Connection, включая создание другого объекта DataReader, пока исходный объект DataReader не будет закрыт.

Доступ к столбцам

После выполнения метода Read доступ к отдельным столбцам возвращенной строки осуществляется по имени или порядковому номеру столбца через объект DataReader. Однако для максимальной производительности объект DataReader предоставляет ряд методов, позволяющих обращаться к значениям столбцов в их собственных типах данных (GetDateTime, GetDouble, GetGuid, GetInt32 и т. д.). Использование типизированных методов доступа при условии, что известен базовый тип данных, сокращает объем преобразований типов, необходимых при извлечении значения столбца.

Извлечение нескольких результирующих наборов при помощи NextResult

При возвращении нескольких результирующих наборов объект DataReader предоставляет метод NextResult для просмотра наборов результатов по порядку. В следующем примере показан объект SqlDataReader, обрабатывающий результаты двух инструкций SELECT с помощью метода ExecuteReader.

Метод NextResult перемещает средство чтения данных на следующий результат.

По умолчанию средство чтения данных располагается на первом результате.

static void RetrieveMultipleResults(SqlConnection connection)

{

SqlCommand command = new SqlCommand(

"SELECT CategoryID, CategoryName FROM dbo.Categories;" +

"SELECT EmployeeID, LastName FROM dbo.Employees", connection);

connection.Open();

SqlDataReader reader = command.ExecuteReader();

while (reader.HasRows)

{

Console.WriteLine("\t{0}\t{1}", reader.GetName(0), reader.GetName(1));

while (reader.Read())

{

Console.WriteLine("\t{0}\t{1}", reader.GetInt32(0), reader.GetString(1));

}

reader.NextResult();

}

reader.Close();

connection.Close();

}

Command

Объект Command позволяет обращаться к командам базы данных для возврата данных, изменения данных, выполнения хранимых процедур и передачи или получения сведений о параметрах.

Каждый поставщик данных .NET Framework, включенный в состав .NET Framework, имеет собственный объект команды, наследуемый от DbCommand. Поставщик данных .NET Framework для SQL Server — объект SqlCommand.

После установки соединения с источником данных при помощи объекта DbCommand можно выполнять команды и возвращать результаты из источника данных.

Создание объекта SqlCommand

Команду можно создать с помощью одного из используемых конструкторов команд для поставщика данных .NET Framework. Конструкторы могут принимать необязательные аргументы, например инструкцию SQL для выполнения в источнике данных, объект DbConnection или объект DbTransaction. Эти объекты также можно настроить как свойства команды. При помощи метода CreateCommand объекта DbConnection также можно создать команду для конкретного соединения. Инструкцию SQL, выполняемую командой, можно настроить с помощью свойства CommandText.

Пример создания через конструктор:

string sql ="INSERT INTO tblExample (columnEx) VALUES (‘ValueEx’)";

SqlConnection connection = new SqlConnection(connString);

SqlCommand cmd = new SqlCommand(sql, connection);

Пример создания путем установки его свойств:

SqlCommand command = new SqlCommand();

command.Connection = connection;

command.CommandText = sql;

command.CommandType = CommandType.Text;

Объект команды имеет свойство CommandType, определяющее тип команды, который указывает способ интерпретации строки команды:

    • Text: Команда SQL, определяющая инструкции, которые выполняются применительно к источнику данных.

    • StoredProcedure: Имя хранимой процедуры.

    • TableDirect: Имя таблицы.

Методы SqlCommand

Каждый из объектов предоставляет методы выполнения команд с учетом типа команды и требуемого возвращаемого значения.

    • ExecuteReader: Возвращает объект DataReader.

    • ExecuteScalar: Возвращает одно скалярное значение. Может возникнуть необходимость вернуть сведения из базы данных, которые представляют собой одиночное значение, а не форму таблицы или поток данных. Метод ExecuteScalar возвращает значение первого столбца первой строки результирующего набора в виде скалярного значения.

    • ExecuteNonQuery: Выполняет команду, которая не возвращает строк. Используя поставщик данных .NET Framework, можно выполнять хранимые процедуры или инструкции языка описания данных DDL (например, CREATE TABLE и ALTER COLUMN) для выполнения операций со схемой в базе данных или в каталоге. Эти команды не возвращают строк, как это делают запросы. Этот метод может быть использован для обработки инструкций SQL, которые изменяют данные, но не возвращают строки, например инструкций INSERT, UPDATE и DELETE. Метод ExecuteNonQuery возвращает значение типа integer, представляющее число строк, затрагиваемых выполненной инструкцией или хранимой процедурой. Если выполняется несколько инструкций, возвращенное значение является суммой количеств записей, затронутых всеми выполненными инструкциями.

    • ExecuteNonQuery: Выполняет команду, которая не возвращает строк.

    • ExecuteXMLReader: Возвращает значение типа XmlReader. Этот метод предусмотрен только для объекта SqlCommand.

Параметры

Объекты команды используют параметры для передачи значений в выражения SQL или хранимые процедуры, обеспечивая проверку типов и правильности. В отличие от текста команд, входные параметры обрабатываются как буквенные значения, а не как исполняемый код. Это помогает защищаться от атак путем внедрения кода SQL, в которых атакующий вставляет команду в выражение SQL, которое ставит под угрозу безопасность сервера. Помимо улучшенной безопасности, параметризованные команды обеспечивают удобный метод организации значений, передающихся в источник данных.

Объект DbParameter можно создать при помощи конструктора или путем добавления его в коллекцию DbParameterCollection с помощью метода Add коллекции DbParameterCollection. Метод Add принимает в качестве входных данных либо аргументы конструктора, либо существующий объект параметра — в зависимости от поставщика данных.

Свойство ParameterDirection

При добавлении параметров необходимо указать свойство ParameterDirection для параметров, не являющихся входными. Свойство может принимать следующие значения:

    • Input: Параметр является входным. Это настройка по умолчанию.

    • InputOutput: Параметр можно использовать как для ввода, так и для вывода.

    • Output: Параметр является выходным.

    • ReturnValue: Параметр представляет значение, возвращаемое как результат операции, например хранимой процедуры, встроенной функции или определяемой пользователем функции.

Указание типов данных параметров

Тип данных параметра зависит от поставщика данных .NET Framework. При указании типа значение Parameter преобразуется в тип поставщика данных .NET Framework до передачи значения в источник данных. Можно также указать тип Parameter универсальным способом, задав свойству DbType объекта Parameter определенное значение DbType.

Использование параметров с объектом SqlCommand и хранимой процедурой

Хотя хранимые процедуры можно вызывать и с помощью инструкции SQL, указывая в ней имя процедуры и ее аргументы, использование коллекции Parameters объекта DbCommand в ADO.NET позволяет более явно задать параметры процедуры, а также обращаться к выходным параметрам и возвращаемым значениям.

Если параметры используются с объектом SqlCommand для выполнения хранимой процедуры SQL Server, то имена параметров, добавляемых в коллекцию Parameters, должны соответствовать именам маркеров параметров в хранимой процедуре.

Для поставщиков данных .NET Framework используются разные способы задания имен и указания параметров и их местозаполнителей. Синтаксис зависит от конкретного источника данных, как описано в следующей таблице. SQL Server обрабатывает параметры в хранимой процедуре как именованные параметры в формате @имяпараметра и ищет соответствующие маркеры параметров.

Следующий пример кода демонстрирует способ создания объекта SqlCommand для выполнения хранимой процедуры путем установки его свойств. Объект SqlParameter используется для задания входных параметров хранимой процедуры. Команда выполняется с помощью метода ExecuteReader.

static void ExampleFunc(SqlConnection connection, string categoryName)

{

SqlCommand command = new SqlCommand();

command.Connection = connection;

command.CommandText = "NameProcedure";

command.CommandType = CommandType.StoredProcedure;

SqlParameter parameter = new SqlParameter();

parameter.ParameterName = "@Name";

parameter.SqlDbType = SqlDbType.NVarChar;

parameter.Direction = ParameterDirection.Input;

parameter.Value = categoryName;

command.Parameters.Add(parameter);

connection.Open();

SqlDataReader reader = command.ExecuteReader();

}

DataAdapter

DataAdapter предоставляет мост между объектом DataSet и источником данных. Класс DataAdapter используется для получения данных из источника данных и заполнения таблиц в DataSet. Класс DataAdapter позволяет также решить задачу по возврату изменений, сделанных в объекте DataSet, обратно в источник данных. В классе DataAdapter используется объект Connection поставщика данных .NET Framework для подключения к источнику данных, а также используются объекты Command для получения из него данных и решения задачи по записи изменений в источник данных.

Каждый поставщик данных .NET Framework, включенный в состав .NET Framework, имеет объект DataAdapter. Поставщик данных .NET Framework для SQL Server — объект SqlDataAdapter.

Заполнение DataSet из DataAdapter

Управление взаимодействием DataSet с существующими источниками данных осуществляется с помощью DataAdapter.

Метод Fill объекта DataAdapter используется для заполнения набора данных DataSet результатами выполнения метода SelectCommand объекта DataAdapter. Метод Fill принимает в качестве аргумента подлежащий заполнению набор данных DataSet, а также объект DataTable или имя объекта DataTable, который должен быть заполнен строками, возвращенными методом SelectCommand.

Метод Fill определяет, должна ли быть добавлена новая строка или обновлена существующая строка, путем проверки значений первичного ключа в строках объекта DataSet и в строках, возвращенных SelectCommand. Если в методе Fill обнаруживается значение первичного ключа какой-то строки в DataSet, которое совпадает со значением первичного ключа строки в результатах, возвращенных SelectCommand, то метод обновляет существующую строку на основании данных из строки, возвращенной SelectCommand. Если строка, возвращенная SelectCommand, имеет значение первичного ключа, не совпадающее ни с одним из значений первичного ключа в строках в DataSet, то метод Fill добавляет новую.

В следующем примере кода создается экземпляр SqlDataAdapter, в котором используется соединение SqlConnection для базы данных Microsoft SQL Server и заполняется объект DataSet.

string queryStr = "SELECT * FROM tblExample";

SqlDataAdapter adapter = new SqlDataAdapter(queryStr, connection);

DataSet dataset = new DataSet();

adapter.Fill(dataset, "tblExample");

Код, показанный в данном примере, не открывает и закрывает Connection явным образом. Если соединение еще не открыто, то метод Fill неявно открывает Connection, которое используется DataAdapter. Если операция Fill открыла соединение, она также закрывает его при завершении Fill. Однако при выполнении нескольких операций, требующих открытого соединения, можно повысить производительность приложения путем явного вызова метода Open объекта Connection, выполнения операций с источником данных и последующего вызова метода Close объекта Connection.

Если объект DataAdapter обнаруживает несколько результирующих наборов, то создает несколько таблиц в DataSet. Таблицы получают добавочное имя по умолчанию TableN, для Table0 начинающееся с «Table». Если имя таблицы передается в качестве аргумента методу Fill, то таблицы получают по умолчанию имя TableNameN с последовательно увеличивающимся суффиксом, но начиная с «TableName», а не с TableName0.

Постраничный просмотр результата запроса

Постраничный просмотр результатов запроса — это процесс возврата результатов запроса небольшими подмножествами данных (страницами). Этот метод часто используется для вывода результатов пользователю в виде небольших фрагментов, с которыми легко работать.

Класс DataAdapter предоставляет возможность возврата одной страницы данных при помощи перегрузок метода Fill. Однако это может быть не лучшим решением для постраничного просмотра большого числа результатов запроса. Хотя класс DataAdapter заполняет целевые объекты DataTable или DataSet только запрошенными записями, при этом все равно используются ресурсы, необходимые для возврата всех результатов запроса. Для возврата страницы данных из источника данных без использования лишних ресурсов задайте для запроса дополнительные критерии, которые ограничат число возвращаемых строки только необходимыми.

В следующем примере кода показано, как использовать метод Fill для возврата первой страницы результатов запроса, где размер страницы — пять записей.

int currentIndex = 0;

int pageSize = 5;

string orderSQL = "SELECT * FROM Orders ORDER BY OrderID";

SqlDataAdapter adapter = new SqlDataAdapter(orderSQL, connection);

DataSet dataSet = new DataSet();

adapter.Fill(dataSet, currentIndex, pageSize, "Orders");

Параметры DataAdapter

Класс DbDataAdapter имеет четыре свойства, которые используются для получения данных из источника данных и обновления данных в нем, все они представляют собой объект Command: SelectCommand возвращает данные из источника данных, а свойства InsertCommand, UpdateCommand и DeleteCommand используются для управления изменениями в источнике данных. Свойство SelectCommand должно быть установлено до вызова метода Fill объекта DataAdapter. Свойства InsertCommand, UpdateCommand или DeleteCommand должны быть установлены до вызова метода Update объекта DataAdapter в зависимости от того, какие изменения были сделаны в данных в DataTable.

Если метод Update обрабатывает вставленную, обновленную или удаленную строку, DataAdapter использует соответствующее свойство Command для обработки действия. Текущие данные об измененной строке передаются в объект Command через коллекцию Parameters.

Parameter.SourceColumn, Parameter.SourceVersion

SourceColumn и SourceVersion могут быть посланы как аргументы в конструктор Parameter или установлены как свойства существующих Parameter.

SourceColumn является именем DataColumn из DataRow, где значение Parameter будет получено (т.е. SourceColumn задает имя исходного столбца, который сопоставляется с объектом DataSet).

SourceVersion задает версию DataRow, которую DataAdapter использует для получения значения.

Значения DataRowVersion, доступные для использования с SourceVersion:

    • Current: Параметр использует текущее значение столбца. Это настройка по умолчанию.

    • Default: Параметр использует DefaultValue столбца.

    • Original: Параметр использует исходное значение столбца.

    • Proposed: Параметр использует предложенное значение.

Следующий пример демонстрирует, как создать SqlDataAdapter. Устанавливается свойство UpdateCommand, и соответствующие им объекты SqlParameter добавляются в коллекцию Parameters.

SqlDataAdapter adapter = new SqlDataAdapter();

adapter.UpdateCommand = new SqlCommand("UPDATE tblExample SET ID = @ID, Column = @Param WHERE ID = @oldID", connection);

adapter.UpdateCommand.Parameters.Add("@ID", SqlDbType.Int,"ID");

adapter.UpdateCommand.Parameters.Add("@Param", SqlDbType.VarChar,40, "Column");

adapter.UpdateCommand.Parameters.Add("@oldID", SqlDbType.Int, ID" ).SourceVersion = DataRowVersion.Original;

Обновление источников данных с помощью объектов DataAdapter

Метод Update объекта DataAdapter вызывается для решения задачи по передаче изменений из DataSet обратно в источник данных. Метод Update, как и метод Fill, принимает в качестве аргументов экземпляр DataSet, а также (необязательно) объект DataTable или имя DataTable. Экземпляр DataSet представляет собой объект DataSet, который содержит выполненные изменения, а DataTable указывает на таблицу, из которой должны быть получены эти изменения. Если ни один объект DataTable не задан, используется первый объект DataTable в DataSet.

Обновление выполняется построчно. Если в DataAdapter обнаруживается изменение в DataRow, то в этом объекте используется команда InsertCommand, UpdateCommand или DeleteCommand для обработки этого изменения. Это позволяет максимально повысить производительность приложения ADO.NET путем задания синтаксиса команды во время разработки, а также, по возможности, за счет применения хранимых процедур. Необходимо явно задавать команды перед вызовом Update. Если вызывается Update, и не существует подходящая команда для конкретного обновления, то активизируется исключение.

Параметры команды могут использоваться в целях указания входных и выходных значений для инструкции SQL или хранимой процедуры применительно к каждой модифицированной строке в DataSet.

В следующем примере показано, как выполнить обновления применительно к модифицированным строкам путем явного задания значения UpdateCommand объекта DataAdapter и вызова его метода Update. Для параметра, указанного в предложении WHERE инструкции UPDATE, используется значение Original объекта SourceColumn. Это важно, поскольку значение Current могло быть изменено, поэтому может не соответствовать этому значению в источнике данных. Значение Original представляет собой значение, которое использовалось для заполнения DataTable из источника данных.

SqlDataAdapter adapter = new SqlDataAdapter("SELECT ID, Column FROM tblExample", connection);

adapter.UpdateCommand = new SqlCommand("UPDATE tblExample SET Column = @Param WHERE ID = @ID", connection);

adapter.UpdateCommand.Parameters.Add("@Param", SqlDbType.VarChar, 40, "Column");

adapter.UpdateCommand.Parameters.Add("@ID", SqlDbType.Int, "ID"

).SourceVersion = DataRowVersion.Original;

DataTable Table = new DataTable();

dataAdpater.Fill(Table);

DataRow Row = Table.Rows[0];

Row["Column"] = "New value";

dataAdpater.Update(Table);

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]