Работа с SqlDataAdapter и DataSet
Ранее для получения данных мы использовали объект SqlDataReader, с помощью которого построчно можно перебрать ответ от сервера базы данных. Но есть и другой способ, который демонстрирует использование объектов SqlDataAdapter и DataSet. DataSet представляет хранилище данных, с которыми можно работать независимо от наличия подключения, а SqlDataAdapter заполняет DataSet данными из БД.
Для получения данных через объект SqlDataAdapter необходимо организовать подключение к БД и выполнить команду SELECT. Есть несколько способов создания SqlDataAdapter:
SqlDataAdapter adapter = new SqlDataAdapter(); SqlDataAdapter adapter = new SqlDataAdapter(command); SqlDataAdapter adapter = new SqlDataAdapter(sql, connection); SqlDataAdapter adapter = new SqlDataAdapter(sql, connectionString);
- Можно использовать конструктор без параметров, а команду SELECT и подключение установить позже
- Можно передать в конструктор объект SqlCommand
- Можно в конструкторе установить sql-выражение SELECT и объект SqlConnection
- Можно в конструкторе установить sql-выражение SELECT и строку подключения
Рассмотрим, как получить данные в DataSet через SqlDataAdapter. Для работы с DataSet особенно удобно использовать элементы управления, которые могут заполняться из внешнего источника данных, например, DataGridView в Windows Forms. Поэтому создадим новый проект по типу Windows Forms Application.
Добавим на единственную форму в проекте элемент DataGridView и определим следующий код формы:
using System.Data; using System.Windows.Forms; using System.Data.SqlClient; namespace AdoNetWinFormsApp < public partial class Form1 : Form < public Form1() < InitializeComponent(); string connectionString = @"Data Source=.\SQLEXPRESS;Initial Catalog=usersdb;Integrated Security=True"; string sql = "SELECT * FROM Users"; using (SqlConnection connection = new SqlConnection(connectionString)) < connection.Open(); // Создаем объект DataAdapter SqlDataAdapter adapter = new SqlDataAdapter(sql, connection); // Создаем объект Dataset DataSet ds = new DataSet(); // Заполняем Dataset adapter.Fill(ds); // Отображаем данные dataGridView1.DataSource = ds.Tables[0]; >> > >
В конструкторе формы в DataGridView загружаются данные. Для загрузки данных создается объект SqlDataAdapter, который принимает объект подключения и sql-выражение SELECT. Затем создается объект DataSet и с помощью метода adapter.Fill() в него загружаются данные. Дальше происходит установка источника данных для DataGridView:
dataGridView1.DataSource = ds.Tables[0];
В качестве источника устанавливается одна из таблиц в DataSet. Каждая таблица представляет объект DataTable, и в DataSet может быть определено несколько таких таблиц. Но в данном случае при выборке в DataSet есть только одна таблица, которую мы можем получить из коллекции Tables по индексу.
DataSet
Ранее для получения данных мы использовали объект SqlDataReader, с помощью которого построчно можно перебрать ответ от сервера базы данных. Но есть и другой способ, который демонстрирует использование объектов DataSet .
Класс DataSet из пространства имен System.Data представляет хранилище или кэш данных в памяти, извлеченных из источника данных. Объект DataSet содержит таблицы, которые представлены типом DataTable . Таблица DataTable , в свою очередь, состоит из столбцов и строк. Каждый столбец представляет объект DataColumn , а строка — объект DataRow .
Для наполнения объекта DataSet данными из источника данных применяется класс System.Data.Common.DataAdapter (который реализует интерфейс System.Data.IDataAdapter ), а точнее его реализации, предназначенные для работы с определенной СУБД.
Для заполнения объекта DataSet у объекта DataAdapter вызывается метод Fill() , в который в качестве параметра передается заполняемый объект DataSet.
Метод Fill() неявно открывает объект подключения, который хранится в свойстве Connection объекта DataAdapter , если это подключение не открыто. Если метод Fill() открывает подключение, то после получения данных метод Fill закрывает это подключение.
Если подключение до вызова метода Fill() ранее уже было открыто, например, с помощью метода Open()/OpenAsync() , метод Fill просто использует это подключение.
SqlDataAdapter
Для работы с БД SQL Server пакет Microsoft.Data.SqlClient как раз предоставляет реализацию DataAdapter в виде класса SqlDataAdapter .
Для получения данных через объект SqlDataAdapter необходимо организовать подключение к БД и выполнить команду SELECT. Есть несколько способов создания SqlDataAdapter:
SqlDataAdapter adapter = new SqlDataAdapter(); SqlDataAdapter adapter = new SqlDataAdapter(command); SqlDataAdapter adapter = new SqlDataAdapter(sql, connection); SqlDataAdapter adapter = new SqlDataAdapter(sql, connectionString);
Для работы SqlDataAdapter необходим объект SqlConnection, либо строка подключения и выполняемое SQL-выражение «SELECT».
Пример наполнения DataSet с помощью SqlDataAdapter:
using System; using System.Data; using Microsoft.Data.SqlClient; namespace HelloApp < class Program < static void Main(string[] args) < string connectionString = "Server=(localdb)\\mssqllocaldb;Database=adonetdb;Trusted_Connection=True;"; string sql = "SELECT * FROM Users"; using (SqlConnection connection = new SqlConnection(connectionString)) < // Создаем объект DataAdapter SqlDataAdapter adapter = new SqlDataAdapter(sql, connection); // Создаем объект DataSet DataSet ds = new DataSet(); // Заполняем Dataset adapter.Fill(ds); >Console.Read(); > > >
В этом случае в DataSet окажутся данные, извлеченные с помощью выражения SELECT * FROM Users .
DataTable, столбцы и строки
Объект DataSet состоит из набора объектов DataTable . Для доступа к таблицам в DataSet определено свойство Tables , которое представляет объект DataTableCollection .
Объект DataTable , в свою очередь, состоит из набора объектов DataColumn — описания столбцов таблицы, которые определяют схему таблицы и которые можно получить через свойство Columns .
Кроме столбцов класс DataTable определяет свойство Rows , которое представляет тип DataRowCollection и которое хранит строки таблицы. Каждая строка представляет класс DataRow .
Для обращения к отдельным ячейкам строки DataRow предлагает ряд свойств, из которых следует выделить следующие:
- Item[Int32] : возвращает или устанавливает значение ячейки по ее индексу. Возвращает значение типа object .
- Item[String] : возвращает или устанавливает значение ячейки по имени столбца. Возвращает значение типа object .
- ItemArray : возвращает или устанавливает значения всех ячеек строки в виде объекта object[]
Теперь используем все выше рассмотренные типы, чтобы получить данные таблицы и вывести их содержимое на консоль:
using System; using System.Data; using Microsoft.Data.SqlClient; namespace HelloApp < class Program < static void Main(string[] args) < string connectionString = "Server=(localdb)\\mssqllocaldb;Database=adonetdb;Trusted_Connection=True;"; string sql = "SELECT * FROM Users"; using (SqlConnection connection = new SqlConnection(connectionString)) < // Создаем объект DataAdapter SqlDataAdapter adapter = new SqlDataAdapter(sql, connection); // Создаем объект Dataset DataSet ds = new DataSet(); // Заполняем Dataset adapter.Fill(ds); // Отображаем данные // перебор всех таблиц foreach (DataTable dt in ds.Tables) < foreach (DataColumn column in dt.Columns) Console.Write($"\t"); Console.WriteLine(); // перебор всех строк таблицы foreach (DataRow row in dt.Rows) < // получаем все ячейки строки var cells = row.ItemArray; foreach (object cell in cells) Console.Write($"\t"); Console.WriteLine(); > > > Console.Read(); > > >
Консольный вывод в моем случае:
Id Age Name 2 32 Alice 3 28 Bob 19 36 Tom 22 34 Tim 23 31 Kate
Хотя DataSet представляет самодостаточный класс, с которым можно работать вне зависимости от применяемой технологии на .NET, однако чаще всего он применяется именно для связи элементов управления для отображения данных c БД, например, элемента DataGridView в Windows Forms.
Объясните работу с DataAdapter, DataSet и DataTable
Доброго времени суток!
Столкнулся с такой проблемой:
Создаю DataAdapter, в который помещаю SQL-запрос (в который, кроме команд SQL, помещаю переменные по типу «SQL-код»+переменная+»SQL-код»+переменная+»SQL-код»), далее открываю соединение с базой, создаю DataTable и с помощью метода DataAdapter.Fill пытаюсь заполнить созданный DataTable данными, полученными из SQL-запроса. (дальше должно было быть заполнение dataGridView через его свойство DataSource равное заполненной таблице DataTable) Но почему-то на том месте кода, где заполняю DataTable данными возникает ошибка «Сбой IErrorInfo.GetDescription с E_FAIL(0x80004005).» с заголовком «OleDbException не обработано».
В связи с этим появились 2 мысли: 1 — что-то не так в SQL-запросе из-за переменных, 2 — как-то не так пользуюсь DataAdapter и DataSet . Остановился на 2-ой. Порывшись в инете пришёл к мысле, что нужно создавать DataSet, потом только DataTable и уже потом как-то засунуть DataTable в DataSet (но как?!), после чего заполнять с помощью DataAdapter.
Подскажите пожалуйста, как засунуть DataTable в DataSet, чтобы я потом мог заполнить DataTable данными из БД (Access) и выгрузить всё это в dataGridView.
P.S. Переменные в SQL-запросе — одна строчная (название таблицы), а другая — int (id нужного значения в таблице).
Лучшие ответы ( 1 )
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
Ответы с готовыми решениями:
Обновление DataTable после изменения DataAdapter
Здравствуйте, возникла такая проблема: есть строка с CheckBoxом при изменении его значения мы.
Волнует скорость DataSet и DataAdapter.Update
При использовании метода Update в базу данных вносятся изменения со всего DataSet’а или система.
DataAdapter методом Fill выгружает в DataSet DataRelation?
Если таблицы связаны и я методом Fill выгружаю их в DataSet то помимо объектов DataTable создаются.
SqlDataAdapter надо ли закрывать
тут все понятно создается подключение открывается заполняется и т.д. ну и закрывается в конце.
посмотрел в MSDN’е можно сделать через SqldataAdapter http://msdn.microsoft.com/ru-r. 3kh8d.aspx ну сделал так, получилось
1 2 3 4 5
using (SqlDataAdapter dataAdapter = new SqlDataAdapter(queryString, connectionString)) { DataTable table = new DataTable(); table.Locale = System.Globalization.CultureInfo.InvariantCulture; dataAdapter.Fill(table);}
собственно Microsoft пишет
SqlDataAdapter создаст и будет поддерживать подключение, созданное с параметром selectConnectionString.
НО как его потом закрыть ? и надо ли вообще его закрывать ? лопатил нет случайно наткнулся на 1 пост в котором писали: