При работе с данными в DataSet мы можем производить с ними различными операции: удалять, изменять, добавлять новые записи. Но все производимые с данными изменения
автоматически не будут сохраняться в БД. Для этого нам еще надо вызвать метод Update объекта SqlDataAdapter
,
который заполнял объект DataSet.
Для модификации данных в БД в соответствии с изменениями в DataSet SqlDataAdapter
использует команды
InsertCommand
, UpdateCommand
и DeleteCommand
. Мы можем сами определить для этих команд
sql-выражения, либо мы можем воспользоваться классом SqlCommandBuilder, который позволяет автоматически сгенерировать нужные выражения.
Например, добавим в DataSet строку, изменим уже имеющиеся данные и используем SqlCommandBuilder для сохранения объектов в базу данных:
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); DataTable dt = ds.Tables[0]; // добавим новую строку DataRow newRow = dt.NewRow(); newRow["Name"] = "Rick"; newRow["Age"] = 24; dt.Rows.Add(newRow); // Изменим значение в столбце Age для первой строки dt.Rows[0]["Age"] = 17; // создаем объект SqlCommandBuilder SqlCommandBuilder commandBuilder = new SqlCommandBuilder(adapter); adapter.Update(ds); // альтернативный способ - обновление только одной таблицы //adapter.Update(dt); // заново получаем данные из бд // очищаем полностью DataSet ds.Clear(); // перезагружаем данные adapter.Fill(ds); // Отображаем данные // перебор всех таблиц foreach (DataColumn column in dt.Columns) Console.Write($"{column.ColumnName}\t"); Console.WriteLine(); // перебор всех строк таблицы foreach (DataRow row in dt.Rows) { // получаем все ячейки строки var cells = row.ItemArray; foreach (object cell in cells) Console.Write($"{cell}\t"); Console.WriteLine(); } } Console.Read(); } } }
Консольный вывод в моем случае:
Id Age Name 2 17 Alice 3 28 Bob 19 36 Tom 22 34 Tim 23 31 Kate 24 26 Rick
Здесь после загрузки данных создается новая строка, которая затем добавляется в DataTable. При вызове у адаптера метода Update()
происходит анализ изменений, которые произошли. И после этого выполняется соответствующая команда. В данном случае так как идет добавление
новой строки, то будет выполняться команда InsertCommand. Однако в данном коде мы нигде явным образом не задаем эту команду, за нас все автоматически
делает SqlCommandBuilder. Для применения этого класса достаточно вызвать его конструктор, в который передается нужный адаптер:
SqlCommandBuilder commandBuilder = new SqlCommandBuilder(adapter);
Причем больше нигде в коде вы этот объект не вызываем.
При необходимости мы можем получить sql-выражения используемых команд:
Console.WriteLine(commandBuilder.GetUpdateCommand().CommandText); Console.WriteLine(commandBuilder.GetInsertCommand().CommandText); Console.WriteLine(commandBuilder.GetDeleteCommand().CommandText);
В моем случае команда обновления будет выглядеть так:
UPDATE [Users] SET [Name]=@p1, [Age]=@p2 WHERE (([Id]=@p3) AND ([Name]=@p4) AND ([Age]=@p5))
Команда вставки:
INSERT INTO [Users] ([Name],[Age]) VALUES (@p1, @p2)
Команда удаления:
DELETE FROM [Users] WHERE (([Id]=@p1) AND ([Name]=@p2) AND ([Age]=@p3))