DataTable, столбцы и строки
Объект DataSet состоит из набора объектов DataTable. Для доступа к таблицам в DataSet определено свойство Tables, которое представляет объект DataTableCollection.
Объект DataTable, в свою очередь, состоит из набора объектов DataColumn - описания столбцов таблицы, которые определяют схему таблицы и которые можно получить через свойство Columns.
Кроме столбцов класс DataTable определяет свойство Rows, которое представляет тип DataRowCollection и которое хранит строки таблицы. Каждая строка представляет класс DataRow.
Для обращения к отдельным ячейкам строки DataRow предлагает ряд свойств, из которых следует выделить следующие:
Item[Int32]: возвращает или устанавливает значение ячейки по ее индексу. Возвращает значение типа object.
Item[String]: возвращает или устанавливает значение ячейки по имени столбца. Возвращает значение типа object.
ItemArray: возвращает или устанавливает значения всех ячеек строки в виде объекта object[]
Теперь используем все выше рассмотренные типы, чтобы получить данные таблицы и вывести их содержимое на консоль:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
|
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($"{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 32 Alice
3 28 Bob
19 36 Tom
22 34 Tim
23 31 Kate
Хотя DataSet представляет самодостаточный класс, с которым можно работать вне зависимости от применяемой технологии на .NET, однако чаще всего он применяется именно для связи элементов управления для отображения данных c БД, например, элемента DataGridView в Windows Forms.
В прошлой теме для получения данных в DataSet приходилось подключаться к БД. Но в реальности DataSet - самодостаточный класс, с которым можно работать без подключения к базе данных, если нам не нужно никакого подключения к БД, не надо загужать данные. Такой сценарий не так сильно распространен и явно требуется не часто, если вообще требуется. Тем не менее рассмотрим, как мы можем работать с объектами DataSet и DataTable без какой-либо базы данных.
Например, создадим вручную в DataSet таблицу, определим ее структуру и добавим в нее данные:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
|
using System;
using System.Data;
namespace HelloApp
{
class Program
{
static void Main(string[] args)
{
DataSet usersSet = new DataSet("UsersSet");
DataTable users = new DataTable("Users");
// добавляем таблицу в dataset
usersSet.Tables.Add(users);
// создаем столбцы для таблицы Users
DataColumn idColumn = new DataColumn("Id", Type.GetType("System.Int32"));
idColumn.Unique = true; // столбец будет иметь уникальное значение
idColumn.AllowDBNull = false; // не может принимать null
idColumn.AutoIncrement = true; // будет автоинкрементироваться
idColumn.AutoIncrementSeed = 1; // начальное значение
idColumn.AutoIncrementStep = 1; // приращении при добавлении новой строки
DataColumn nameColumn = new DataColumn("Name", Type.GetType("System.String"));
DataColumn ageColumn = new DataColumn("Age", Type.GetType("System.Int32"));
ageColumn.DefaultValue = 1; // значение по умолчанию
users.Columns.Add(idColumn);
users.Columns.Add(nameColumn);
users.Columns.Add(ageColumn);
// определяем первичный ключ таблицы Users
users.PrimaryKey = new DataColumn[] { users.Columns["Id"] };
DataRow row = users.NewRow();
row.ItemArray = new object[] { null, "Tom", 36 };
users.Rows.Add(row); // добавляем первую строку
users.Rows.Add(new object[] { null, "Bob", 29 }); // добавляем вторую строку
Console.Write("Id\t Имя\t Возраст\t");
Console.WriteLine();
foreach (DataRow r in users.Rows)
{
foreach (var cell in r.ItemArray)
Console.Write("{0}\t", cell);
Console.WriteLine();
}
Console.Read();
}
}
}
|
Консольный вывод программы:
Id Имя Возраст
1 Tom 36
2 Bob 29
Разберем весь код. Сначала создаются объекты DataSet и DataTable, в конструктор которых передается название. Затем создается три столбца DataColumn. Каждый столбец в конструкторе принимает два параметра: имя столбца и его тип.
1
|
DataColumn idColumn = new DataColumn("Id", Type.GetType("System.Int32"));
|
Причем для столбца Id устанавливается, что значения этого столбца должны иметь уникальное значение, не должны принимать null, и их значение при добавлении нового объекта будет инкрементироваться на единицу. То есть фактически это стандартный столбец Id, как в большинстве баз данных.
Далее создается еще два столбца - nameColumn и ageColumn. Затем устанавливается первичный ключ для таблицы с помощью свойства PrimaryKey:
1
|
users.PrimaryKey = new DataColumn[] { users.Columns["Id"] };
|
В роли первичного ключа выступает столбец Id. Но мы также можем использовать набор различных столбцов для создания составного ключа.
После определения схемы таблицы в нее добавляются две строки:
1
2
3
4
|
DataRow row = users.NewRow();
row.ItemArray = new object[] { null, "Tom", 36 };
users.Rows.Add(row); // добавляем первую строку
users.Rows.Add(new object[] { null, "Bob", 29 }); // добавляем вторую строку
|
Значения в метод users.Rows.Add() можно передать как напрямую в виде массива объектов, так и в виде объекта DataRow. При этом нам надо передать ровно столько значений, сколько в таблице столбцов. Однако поскольку первый столбец Id устанавливается через автоинкремент, мы можем передать значение null - оно все равно будет игнорироваться. Также мы можем опустить значение для третьего столбца - Age, так как у него установлено свойство DefaultValue, которое устанавливает значение по умолчанию, если значение отсутствует:
1
|
users.Rows.Add(new object[] { null, "Bob", 29 });
|
И в конце идет перебор строк таблицы.
Кроме добавления мы можем производить и другие операции со строками. Например, мы можем получить строку по индексу:
1
|
DataRow row = users.Rows[0]; // первая строка
|
Получив строку по индексу, можно изменить ее ячейки. Изменить ячейку можно, используя либо индекс, либо название столбца. Например, изменение третий ячейки (индекс столбца - 2):
1
|
users.Rows[0][2] = 30; //третьей ячейке первой строки присваивается значение 30
|
Или изменение ячейки для столбца с названием "Age":
1
|
users.Rows[0]["Age"] = 30;
|
И также можно удалять строку:
1
2
3
4
|
users.Rows.RemoveAt(1); // удаление второй строки по индексу
// другой сопосб удаления
DataRow row = users.Rows[0];
users.Rows.Remove(row);
|
Используя метод Select() объекта DataTable мы легко можем найти строки, которые соответствуют определенному критерию. Например, получим строки, в которых возраст больше 30:
1
2
3
|
var selectedUsers = users.Select("Age > 30");
foreach (var user in selectedUsers)
Console.WriteLine($"{user["Name"]} - {user["Age"]}");
|
При работе с данными в DataSet мы можем производить с ними различными операции: удалять, изменять, добавлять новые записи. Но все производимые с данными изменения автоматически не будут сохраняться в БД. Для этого нам еще надо вызвать метод Update объекта SqlDataAdapter, который заполнял объект DataSet.
Для модификации данных в БД в соответствии с изменениями в DataSet SqlDataAdapter использует команды InsertCommand, UpdateCommand и DeleteCommand. Мы можем сами определить для этих команд sql-выражения, либо мы можем воспользоваться классом
Do'stlaringiz bilan baham: |