Большинство приложений работают с базами данных. Любой программист из крупной компании подтвердит, что роль баз данных в мире вычислительных технологий очень велика. Обладая умением оперировать с базами данных, можно создавать самые разнообразные и действительно полезные приложения.
Возможно, у вас на компьютере уже установлена система управления базами данных, например, Microsoft Access. Лучшая альтернатива – это Microsoft SQL Server Express Edition, с помощью которого вы научитесь работать с базами данных SQL Server, используемыми во многих крупнейших компаниях по всему миру. SQL Server Express включен в пакет установки Visual C# Express, так что, скорее всего, на вашем компьютере он уже установлен.
Для работы с базами данных в библиотеке .NET Framework предусмотрены классы пространства имен System.Data. База данных в корне отличается от таких объектов, как изображения или документы текстовых редакторов, которые часто называют неструктурированными. Информация в базе данных структурирована и обычно хранится в таблицах, а каждая таблица состоит из строк и столбцов.
В программировании строки называют записями, а столбцы задают поля записи. Столбец таблицы определяет тип данных, хранимых в поле записи.
Ниже представлена таблица базы данных, содержащая информацию о планетах. Она имеет следующие столбцы: PlanetName (название планеты), DistanceFromSun (расстояние до Солнца) и Inhabitants (обитатели).
| PlanetName | DistanceFromSun (единица измерения – тысяча километров) | Inhabitants |
|---|---|---|
| Меркурий | 57909 | Меркуриане |
| Венера | 108200 | Венериане |
| Земля | 149600 | Земляне |
| Марс | 227940 | Марсиане |
| Юпитер | 778400 | Юпитериане |
| Знок | 7208100 | Знокиане |
| Сатурн | 1423600 | Сатурниане |
| Уран | 2867000 | Ураниане |
| Нептун | 4488400 | Нептуниане |
| Плутон | 5909600 | Плутониане |
Из таблицы видно, что, например, Венера находится на расстоянии 108 200 тысяч километров от Солнца, а существа, ее населяющие, называются венериане.
Вот еще одна таблица, в которой содержатся сведения о ежегодной численности обитателей разных планет.
Эта совершенно секретная информация, нигде ранее не обнародованная, была получена с инопланетного звездолета, потерпевшего крушение в самой глубине пустыни Гоби. Иметь возможность ознакомиться с ней – большая честь. Очевидно, представители инопланетной цивилизации тоже используют базы данных SQL Server, что и позволило нам привести эти сведения в качестве примера.
| PlanetName | Year | |
|---|---|---|
| Меркурий | 2008 | 40000 |
| Венера | 2008 | 25 |
| Земля | 2008 | 6000000000 |
| Марс | 2008 | 450000 |
| Юпитер | 2008 | 8326300200 |
| Знок | 2008 | 325000 |
| Сатурн | 2008 | 1000000 |
| Уран | 2008 | 7849345700 |
| Нептун | 2008 | <NULL> |
| Плутон | 2008 | <NULL> |
| Меркурий | 2009 | 35000 |
| Венера | 2009 | 3 |
| Земля | 2009 | 6500000000 |
| Марс | 2009 | 326800 |
| Юпитер | 2009 | 8451780500 |
| Знок | 2009 | 8700 |
| Сатурн | 2009 | 750000 |
| Уран | 2009 | 8237456000 |
| Нептун | 2009 | <NULL> |
| Плутон | 2009 | <NULL> |
Если продолжить разговор о Венере, то, обратите внимание, что в 2008 г. на Венере обитало 25 венериан, а через год, вероятно, в результате извержений вулканов, их осталось всего трое.
Не следует путать базы данных с электронными таблицами. Хотя способ представления данных в электронных таблицах внешне похож на тот, что использовался в приведенных выше примерах, обработка данных происходит в них иначе.
Существует множество разнообразных систем управления базами данных: Microsoft Access, Oracle,
Проще всего включить в код C# фрагмент на "языке базы данных", с помощью которого выполняется запрос к базе данных на получение нужных столбцов и строк.
(По правде говоря, существует еще и промежуточный уровень – ADO.NET, но сейчас мы не станем заострять на нем внимание.)
Много лет назад специалисты по базам данных договорились об использовании "единого языка баз данных", который понимали бы большинство существующих баз данных. Они назвали его SQL (от англ. Structured

Приступая к разговору о том, как использовать C# при работе с базами данных, сначала познакомимся с основами языка SQL. Ниже приведены примеры операторов на языке SQL и описывается результат их выполнения.
Основными командами SQL являются:
Приведем примеры каждой команды.
Как правило, оператор SELECT записывается следующим образом:
SELECT <имена извлекаемых столбцов> FROM <имена одной или нескольких таблиц базы данных> WHERE <условие выбора>
Рассмотрим пример выбора данных оператором SELECT:
SELECT * FROM PLANET
Символ звездочка * означает выбор всех столбцов таблицы. Поэтому данный оператор вернет из базы данных всю таблицу Planet со всеми строками и столбцами.
Рассмотрим оператор
SELECT PlanetName, Inhabitants FROM PLANET
Этот запрос возвращает столбцы PlanetName и Inhabitants со всеми строками из таблицы PLANET.
| PlanetName | Inhabitants |
|---|---|
| Меркурий | Меркуриане |
| Венера | Венериане |
| Земля | Земляне |
| Марс | Марсиане |
| Юпитер | Юпитериане |
| Знок | Знокиане |
| Сатурн | Сатурниане |
| Уран | Ураниане |
| Нептун | Нептуниане |
| Плутон | Плутониане |
Запрос
SELECT PlanetName, Inhabitants FROM PLANET WHERE PlanetName='Венера'
возвращает столбцы PlanetName и Inhabitants из таблицы PLANET. В результат его выполнения будут включены только те строки, которые содержат значение Венера в столбце PlanetName.
| PlanetName | Inhabitants |
|---|---|
| Венера | Венериане |
Запрос:
SELECT PlanetName, Population FROM POPULATION WHERE Population<100000
возвращает из таблицы строки столбцов PlanetName и , для которых значение столбца меньше 100000.
| PlanetName | |
|---|---|
| Меркурий | 40000 |
| Венера | 25 |
| Нептун | <NULL> |
| Плутон | <NULL> |
| Меркурий | 35000 |
| Венера | 3 |
| Знок | 8700 |
| Нептун | <NULL> |
| Плутон | <NULL> |
Как правило, оператор INSERT записывается следующим образом:
INSERT INTO <таблица базы данных, к которой добавляются строки> (<названия столбцов, в которые будут добавляться значения>) VALUES (<значения, которые будут вставлены в указанные столбцы>)
Пример:
INSERT INTO PLANET (PlanetName, DistanceFromSun, Inhabitants) VALUES (Флафф, 23500000, 'Флаффиане')
Оператор INSERT добавляет в таблицу PLANET новую строку. Он не возвращает какого-либо результата в программу, но после его выполнения таблица примет вот такой вид:
| PlanetName | DistanceFromSun | Inhabitants |
|---|---|---|
| Меркурий | 57909 | Меркуриане |
| Венера | 108200 | Венериане |
| Земля | 149600 | Земляне |
| Марс | 227940 | Марсиане |
| Юпитер | 778400 | Юпитериане |
| Знок | 7208100 | Знокиане |
| Сатурн | 1423600 | Сатурниане |
| Уран | 2867000 | Ураниане |
| Нептун | 4488400 | Нептуниане |
| Плутон | 5909600 | Плутониане |
| Флафф | 23500000 | Флаффиане |
Оператор UPDATE записывается следующим образом:
UPDATE <таблица базы данных, в которую вносятся изменения> SET <названия столбцов, в которые необходимо внести изменения> = <новые значения> WHERE <условия>
Пример:
UPDATE PLANET SET PlanetName= 'Стафф', Inhabitants='Стаффиане' WHERE PlanetName='Флафф'
Оператор изменяет некоторые значения в той строке, где столбец PlanetName имеет значение "Флафф". Результат выполнения операции программе не возвращается, но таблица примет вот такой вид:
| PlanetName | DistanceFromSun | Inhabitants |
|---|---|---|
| Меркурий | 57909 | Меркуриане |
| Венера | 108200 | Венериане |
| Земля | 149600 | Земляне |
| Марс | 227940 | Марсиане |
| Юпитер | 778400 | Юпитериане |
| Знок | 7208100 | Знокиане |
| Сатурн | 1423600 | Сатурниане |
| Уран | 2867000 | Ураниане |
| Нептун | 4488400 | Нептуниане |
| Плутон | 5909600 | Плутониане |
| Стафф | 23500000 | Стаффиане |
Если рассмотреть таблицы внимательно, то можно заметить, что между таблицами PLANET и существует связь: и в той и в другой есть столбец с именем PlanetName, который связывает обе таблицы. Благодаря этой связи можно собрать всю информацию об определенной планете.
Например, можно выбрать из обеих таблиц все строки, касающиеся Венеры:
|
|
|||||||||||||||||||||
А затем объединить полученные данные в одну большую таблицу:
SELECT * FROM PLANET INNER JOIN POPULATION ON PLANET.PlanetName=POPULATION.planetName WHERE PlanetName='Венера'
| PLANETS_AND_POPULATION | ||||
|---|---|---|---|---|
| PlanetName | DistanceFromSun | Inhabitants | Year | |
| Венера | 108200 | Венериане | 2008 | 25 |
| Венера | 108200 | Венериане | 2009 | 3 |
При работе с определенной СУБД необходимо учитывать ее особенности. С этой целью вводится понятие "провайдер данных" – у каждой СУБД он свой. С точки зрения программиста провайдер данных — это набор классов, обеспечивающих связь с базой и осуществляющих доступ к данным. Так, например, за связь с базой данных Microsoft SQL Server отвечает класс
Программный код меняется в зависимости от того, с какой базой предстоит работать. Для демонстрации возможностей
Три варианта базы данных Planets помещены в каталог с именем databases. Файлы Planets.mdf и Planets.ldf, задают базу данных SQL Server, файл Planets.accdb создан для базы данных Access 2007, а Planets.
В программном коде указывается путь к файлам базы данных, поэтому папка databases должна находиться в том же каталоге, где находится программа, задающая решение, — в нашем случае это файл Examples.sln.
При работе с базой данных SQL Server программный код зависит от того, с какой версией СУБД приходится работать — с Microsoft SQL Server или Microsoft SQL Server Express Edition.
В приведенном ниже примере показаны четыре возможных варианта работы:
Три варианта закомментированы, а один готов к использованию, в данном тексте это вариант работы с Microsoft SQL Server. В зависимости от того, что установлено на компьютере читателя, следует нужный вариант раскомментировать, а ненужный — закомментировать.
У большинства пользователей на компьютерах установлен комплект Microsoft Office, возможно, в нем имеется и приложение Access, так что для начала можно поработать с базами данных, подготовленными в этом приложении.
Когда вам понадобятся более широкие возможности программирования, мы рекомендуем вам установить SQL Server Express. К тому же умение работать с SQL Server гораздо выше ценится в деловой сфере, и чем скорее вы освоите этот инструмент, тем лучше. Загрузить его можно бесплатно с сайта Microsoft: http://www.microsoft.com/.
Далее в трех примерах программ на C# мы будем использовать классы Connection, Command, DataReader, DataAdapter. Префиксы Sql и OleDb указывают на то, с каким вариантом базы данных Planets мы работаем.
Пример программы 4.1
Следующая программа подключается к базе данных и посылает ей SQL-запрос. Затем выполняется несколько циклов получения результата запроса, после чего полученные результаты передаются в элемент управления ListBox и отображаются в списке.
using System.Windows.Forms;
using System.Data;
// Пространство имен для работы с базами данных SQL Server
using System.Data.SqlClient;
using System.Drawing;
// Пространство имен для работы с базами данных Access
using System.Data.OleDb;
class SimpleDataAccess : Form
{
public SimpleDataAccess()
{
// Указываем заголовок окна
this.Text = "Работа с базой данных. Чтение данных.";
// Добавляем элементы управления - метку и список
Label labelCaption = new Label();
labelCaption.Text = "Планеты солнечной системы!";
labelCaption.Location = new Point(30, 10);
labelCaption.Width = 200;
labelCaption.Parent = this;
ListBox listPlanets = new ListBox();
listPlanets.Location = new Point(30, 50);
listPlanets.Width = 100;
listPlanets.Parent = this;
// Формируем запрос к базе данных -
//запрашиваем информацию о планетах
string sql = "SELECT * FROM PLANET";
string connectionString;
/*
//Вариант 1
// Подключаемся к базе данных SQL Server Express Edition
// Указываем физический путь к базе данных PLANETS
string dbLocation =
("../../../databases/planets.mdf");
connectionString = @"data source=.\SQLEXPRESS;" +
"User Instance=true;Integrated Security=SSPI;" +
"AttachDBFilename=" + dbLocation;
SqlConnection connection1 = new SqlConnection(connectionString);
*/
//Вариант 2
// Подключаемся к базе данных SQL Server 2005
connectionString =
"data source = localhost; Initial Catalog = Planets;" +
"Integrated Security = SSPI";
SqlConnection connection1 = new SqlConnection(connectionString);
//Открываем соединение
connection1.Open();
SqlCommand command1 = new SqlCommand(sql, connection1);
SqlDataReader dataReader1 = command1.ExecuteReader();
// Организуем циклический перебор полученных записей
//и выводим название каждой планеты в список
while (dataReader1.Read())
{
listPlanets.Items.Add(dataReader1["PlanetName"]);
}
// Очистка
dataReader1.Close();
connection1.Close();
/*
//Вариант 3. Связывание с базой данных Access 2003 - *.mdb
connectionString = "Provider=Microsoft.Jet.OLEDB.4.0;" +
@"Data Source= ../../../databases/planets.mdb";
//Вариант 4. Связывание с базой данных Access 2007 - *.accdb
connectionString = "Provider=Microsoft.Ace.OLEDB.12.0;" +
@"Data Source= ../../../databases/planets.accdb";
OleDbConnection connection = new OleDbConnection(connectionString);
connection.Open();
OleDbCommand command = new OleDbCommand(sql, connection);
OleDbDataReader dataReader = command.ExecuteReader();
// Организуем циклический перебор полученных записей
//и выводим название каждой планеты в список
while (dataReader.Read())
{
listPlanets.Items.Add(dataReader["PlanetName"]);
}
// Очистка
dataReader.Close();
connection.Close();
* */
}
static void Main()
{
// Создаем и запускаем форму
Application.Run(new SimpleDataAccess());
}
}

Пример программы 4.2
В этой программе на экран выводится несколько столбцов данных. Для их представления мы воспользуемся элементом DataGridView.
Программа выполняет тот же запрос, что и в предыдущем примере, но помещает результат в объект , который подключается к элементу управления DataGridView, а тот автоматически отображает все данные.
Подключение источника данных к визуальному элементу управления называется привязкой, или связыванием данных.
using System.Windows.Forms;
using System.Data;
// Пространство имен для работы с базами данных SQL Server
using System.Data.SqlClient;
using System.Drawing;
// Пространство имен для работы с базами данных Access
using System.Data.OleDb;
class DataInGrid : Form
{
public DataInGrid()
{
//Изменяем размеры формы
this.Width = 450;
this.Height = 400;
// Указываем заголовок окна
this.Text = "Одностороннее связывание:" +
" база данных и элемент Grid.";
// Добавляем элементы управления - метку и таблицу
Label labelCaption = new Label();
labelCaption.Text = "Планеты солнечной системы!";
labelCaption.Location = new Point(60, 10);
labelCaption.Width = 200;
labelCaption.Parent = this;
// Добавляем элемент DataGridView на форму
DataGridView dataGridView1 = new DataGridView();
dataGridView1.Width = 350;
dataGridView1.Height = 250;
dataGridView1.Location = new Point(20, 50);
dataGridView1.DataMember = "Table";
dataGridView1.AutoResizeColumns();
this.Controls.Add(dataGridView1);
// Формируем запрос к базе данных -
//запрашиваем информацию о планетах
string sql = "SELECT * FROM PLANET";
string connectionString;
// DataSet сохраняет данные в памяти
//данные хранятся в виде таблиц данных DataTable
DataSet dataSet1 = new DataSet();
/*
//Вариант 1
// Подключаемся к базе данных SQL Server Express Edition
// Указываем физический путь к базе данных PLANETS
string dbLocation =
("../../../databases/planets.mdf");
connectionString = @"data source=.\SQLEXPRESS;" +
"User Instance=true;Integrated Security=SSPI;" +
"AttachDBFilename=" + dbLocation;
SqlConnection connection1 = new SqlConnection(connectionString);
*/
/*
//Вариант 2
// Подключаемся к базе данных SQL Server 2005
connectionString =
"data source = localhost; Initial Catalog = Planets;" +
"Integrated Security = SSPI";
SqlConnection connection1 = new SqlConnection(connectionString);
//Открываем соединение
connection1.Open();
// DataAdapter - посредник между базой данных и DataSet
SqlDataAdapter sqlDataAdapter1 = new SqlDataAdapter();
// Создаем объект DataAdapter,
//передаем ему данные запроса
sqlDataAdapter1.SelectCommand =
new SqlCommand(sql, connection1);
// Данные из адаптера поступают в DataSet
sqlDataAdapter1.Fill(dataSet1);
// Связываем данные с элементом DataGridView
DataGridView1.DataSource = dataSet1;
// Очистка
connection1.Close();
* */
/*
//Вариант 3. Связывание с базой данных Access 2003 - *.mdb
connectionString = "Provider=Microsoft.Jet.OLEDB.4.0;" +
@"Data Source= ../../../databases/planets.mdb";
*/
//Вариант 4. Связывание с базой данных Access 2007 - *.accdb
connectionString = "Provider=Microsoft.Ace.OLEDB.12.0;" +
@"Data Source= ../../../databases/planets.accdb";
OleDbConnection connection = new OleDbConnection(connectionString);
connection.Open();
OleDbDataAdapter dataAdapter = new OleDbDataAdapter();
dataAdapter.SelectCommand = new OleDbCommand(sql, connection);
dataAdapter.Fill(dataSet1);
dataGridView1.DataSource = dataSet1;
// Очистка
connection.Close();
}
static void Main()
{
// Создаем и запускаем форму
Application.Run(new DataInGrid());
}
}
Пример программы 4.3
Научившись отображать данные с помощью элемента управления DataGridView, вы, наверное, обратили внимание, что внесенные в базу изменения не сохраняются. Поэтому применим другой подход и осуществим "двухстороннюю привязку данных", которая позволит не только просматривать открывшуюся таблицу, но и вводить изменения в элемент DataGridView, добавляя новые строки, изменяя содержимое имеющихся строк и удаляя ненужные. Объекты класса DataAdapter способны выполнять как операцию Select, получая данные запроса из базы данных, так и команды Insert, Update, Delete, изменяя содержимое таблицы базы данных.
Здесь мы позволим себе маленькую хитрость (это называется "повысить производительность труда") и не станем самостоятельно прописывать операторы UPDATE и INSERT. Пространство имен System.Data содержит небольшой, но очень полезный класс CommandBuilder, который умеет создавать команды SQL и автоматически их выполнять.
using System;
using System.Windows.Forms;
using System.Data;
// Пространство имен для работы с базами данных SQL Server
using System.Data.SqlClient;
using System.Drawing;
using System.Diagnostics;
class DataInOutGrid: Form
{
SqlDataAdapter dataAdapter;
DataGridView dataGridView;
public DataInOutGrid()
{
//Изменяем размеры формы
this.Width = 450;
this.Height = 400;
// Указываем заголовок окна
this.Text = "Двустороннее связывание:" +
" база данных и элемент Grid.";
// Добавляем элементы управления -
//метку, таблицу и командную кнопку
Label labelCaption = new Label();
labelCaption.Text = "Планеты!";
labelCaption.Location = new Point(60, 10);
labelCaption.Width = 200;
labelCaption.Parent = this;
// Добавляем элемент DataGridView на форму
dataGridView = new DataGridView();
dataGridView.Width = 350;
dataGridView.Height = 250;
dataGridView.Location = new Point(20, 50);
dataGridView.AutoResizeColumns();
this.Controls.Add(dataGridView);
// Добавляем командную кнопку
Button buttonSave = new Button();
buttonSave.Location = new Point(100, 320);
buttonSave.Width = 220;
buttonSave.Text = "Сохранить изменения в базе данных!";
buttonSave.Click +=
new System.EventHandler(ButtonSave_Click);
buttonSave.Parent = this;
// Формируем запрос к базе данных -
//запрашиваем информацию о планетах
string sql = "SELECT * FROM PLANET";
string connectionString;
// DataTable сохраняет данные в памяти как таблицу
DataTable dataTable = new DataTable();
/*
//Вариант 1
// Подключаемся к базе данных SQL Server Express Edition
// Указываем физический путь к базе данных PLANETS
string dbLocation =
("../../../databases/planets.mdf");
connectionString = @"data source=.\SQLEXPRESS;" +
"User Instance=true;Integrated Security=SSPI;" +
"AttachDBFilename=" + dbLocation;
SqlConnection connection1 = new SqlConnection(connectionString);
*/
//Вариант 2
// Подключаемся к базе данных SQL Server 2005
connectionString =
"data source = localhost; Initial Catalog = Planets;" +
"Integrated Security = SSPI";
SqlConnection connection = new SqlConnection(connectionString);
//Открываем соединение
connection.Open();
//Создаем команду
SqlCommand sqlCommand = new SqlCommand(sql, connection);
//Создаем адаптер
// DataAdapter - посредник между базой данных и DataSet
dataAdapter = new SqlDataAdapter(sqlCommand);
//Создаем построитель команд
//Для адаптера становится доступной команда Update
SqlCommandBuilder commandBuilder =
new SqlCommandBuilder(dataAdapter);
// Данные из адаптера поступают в DataTable
dataAdapter.Fill(dataTable);
// Связываем данные с элементом DataGridView
dataGridView.DataSource = dataTable;
// Очистка
connection.Close();
}
static void Main()
{
// Создаем и запускаем форму
Application.Run(new DataInOutGrid());
}
void ButtonSave_Click(object sender, System.EventArgs args)
{
try
{
dataAdapter.Update((DataTable)dataGridView.DataSource);
MessageBox.Show("Изменения в базе данных выполнены!",
"Уведомление о результатах", MessageBoxButtons.OK);
}
catch(Exception)
{
MessageBox.Show("Изменения в базе данных выполнить не удалось!",
"Уведомление о результатах", MessageBoxButtons.OK);
}
}
}
На следующем рисунке показано содержимое базы данных, в которую добавлены две строки с названиями недавно открытых фантастических планет Солярис и Обитаемый остров (или коротко – Остров).

Поэкспериментируйте, изменяя существующие значения и вводя новые. Нажмите кнопку "Сохранить изменения" и закройте форму. Перезапустив программу, убедитесь, что все значения были сохранены в базе данных. Если вы работаете с Access, то измените код в соответствии с образцом, приведенным в программах Example 12 и Example 13.
Классы пространства имен System.Xml позволяют работать с XML-данными разными способами. Наиболее часто выполняются следующие задачи:
Язык XML (от англ. eXtensible Markup Language – расширяемый язык разметки) предназначен для хранения структурированных данных. Данные, хранящиеся в формате XML, можно передавать между программами. Поскольку данные в XML структурированные, в некоторых случаях использование этого формата может заменить базы данных. Кроме этого, у XML есть еще много других полезных применений.
Язык XML широко распространен, и, скорее всего, вы уже слышали о нем. Этот язык удобно воспринимать как человеку, так и машине. Большая часть программного кода, с которыми работают различные вычислительные системы, обычным людям кажутся китайской грамотой, но XML-документы записываются почти как обычный текст.
Например, можно составить XML-документ для хранения на диске географических данных:
<?xml version="1.0" encoding="utf-8" ?>
-<Планета>
Земля
- <Континент>
Южная Америка
<Страна столица="Рио-де-Жанейро">
Бразилия
</Страна>
<Страна столица="Буэнос-Айрес">
Аргентина
</Страна>
</Континент>
- <Континент>
Азия
<Страна столица="Дели">
Индия
</Страна>
<Страна столица="Бангкок">
Тайланд
</Страна>
</Континент>
</Планета>
|
Каждый XML-документ начинается со строки <?xml version="1.0" encoding="utf-8" ?>. Встретив такую строку, программа будет знать, что имеет дело именно с XMLСтроки заключенные в треугольные скобки ( Внешний блок Планета Блоки более глубокого уровня вложения, содержат информацию о странах данного континента Еще один |
XML весьма похож на другой язык разметки HTML, но в HTML набор тегов фиксирован, и у каждого тега есть свое строго определенное назначение и правила написания. В XML можно определять собственные теги, но при этом все равно нужно соблюдать синтаксические правила языка разметки.
Далее мы обсудим значение двух терминов, без знания которых невозможно дальнейшее изучение языка XML.
XML-документ - это запись, состоящая из отдельных элементов. Каждый элемент начинается с открывающего тега, заключенного в треугольные скобки ( <> ) – и заканчивается закрывающим тегом ( </> ).
Имя элемента задается в открывающем теге и повторяется в закрывающем теге, а между открывающим и закрывающим тегами находится его содержание. В содержание тега могут быть вложены другие теги. Теги с одним именем нередко повторяются, даже если они не вложены один в другой.
В приведенном выше XML-документе один из элементов с именем <Континент> имеет значение "Южная Америка". В него вложены два элемента с именем <Страна>, содержательно задающие названия стран этого континента.
| Имя элемента в открывающем теге | Значение | Закрывающий тег |
|---|---|---|
| <Страна> | Бразилия | </Страна> |
| <Школьник> | Ваня Курочкин | </Школьник> |
В открывающем теге можно задавать дополнительные свойства элемента. Для этого используются атрибуты. Каждый атрибут задается парой "имя = "значение"". Например, если для элемента <Страна> надо указать столицу, то можно создать атрибут элемента с именем "столица". А для элемента <Школьник> задать атрибуты "возраст" и "класс". В приведенном ниже примере у элемента "Страна" со значением "Аргентина" атрибут "столица" имеет значение "Буэнос-Айрес".
| Открывающий тег | Значение элемента | Закрывающий тег | ||||
|---|---|---|---|---|---|---|
| Имя элемента | Имя атрибута | Значение атрибута | ||||
<Страна |
столица |
= |
"Буэнос-Айрес" |
> |
Аргентина |
</Страна> |
Читать подобные документы не составляет труда, а поскольку они имеют четкую структуру, то и компьютер можно научить этому без особых проблем. Например, составить такой набор инструкций: "Начать просмотр документа; при нахождении символа " < " — читать имя элемента. При нахождении символа " > " — читать значение элемента..." и так далее.
Некоторые элементы могут иметь только атрибуты и не иметь значения и содержания. Тогда открывающий и закрывающий теги объединяются. Например, элемент <Страна> можно задать следующим образом:
<Страна название = "Аргентина" столица = "Буэнос-Айрес" />
Для описания элемента использовались два атрибута, но не значение элемента.
Пример программы 4.4
Следующая программа считывает данные из XML-файла и отображает их на форме.
В ней используются три класса из пространства имен System.Xml:
XmlDocument. Объекты этого класса задают Xml-документ. При создании объекта содержимое документа может быть прочитано из файла, получено из других источников или создано в ходе работы программы.XmlNodeList. Объекты этого класса могут содержать некоторый список элементов XML-документа, найденный, например, в результате поиска.XmlNode. Объект этого класса задает один XML-элемент.Для поиска нужных фрагментов XML-документа в программе используются так называемые выражения . Они позволяют указать, какие именно элементы необходимо извлечь из XML-документа. Выражение вида "/континент/страна" означает: "найти все элементы с именем "страна", вложенные в элемент с именем "континент"".
using System;
using System.Windows.Forms;
using System.Drawing;
// Пространство имен для работы с XML-данными
using System.Xml;
//Пространство имен для работы с выражениями xPath
using System.Xml.XPath;
class XmlRetriever: Form
{
ComboBox comboBox1;
Button button1;
ListBox listBox1;
RichTextBox richTextBox1;
XmlDocument xmlDoc;
// Метод-конструктор нашего класса
public XmlRetriever()
{
// Задаем заголовок и размеры окна
this.Text = "Работа с XML-документом";
this.Size = new Size(400, 400);
// Создаем объект XmlDocument, используя xml-файл
xmlDoc = new XmlDocument();
xmlDoc.Load("../../docs/Planets.xml");
// Создаем объект TextBox для вывода данных
richTextBox1 = new RichTextBox();
richTextBox1.Dock = DockStyle.Top;
richTextBox1.AcceptsTab = true;
richTextBox1.Height = 180;
richTextBox1.ReadOnly = true;
richTextBox1.BackColor = Color.Silver;
// Помещаем XML-данные в элемент TextBox
richTextBox1.Text = xmlDoc.OuterXml;
this.Controls.Add(richTextBox1);
// Создаем объект ComboBox
// В элементы списка этого объекта записываем
//различные выражения XPath,
//позволяющие искать нужные элементы XML-документа
comboBox1 = new ComboBox();
comboBox1.Location = new Point(0, 200);
comboBox1.Width = 300;
comboBox1.Items.Add("/Планета");
comboBox1.Items.Add("/Планета/Континент");
comboBox1.Items.Add("/Планета/Континент/Страна");
comboBox1.Items.Add(
"/Планета/Континент/Страна[@столица='Рио-де-Жанейро']");
comboBox1.SelectedIndex = 0;
this.Controls.Add(comboBox1);
// Создаем командную кнопку для поиска и отображения
// соответствующих элементов Xml-документа
button1 = new Button();
button1.Text = "Получить данные";
button1.Location = new Point(100, 230);
button1.Width = 120;
button1.Click += new EventHandler(Button1_Click);
this.Controls.Add(button1);
// Создаем элемент ListBox для отображения элементов
listBox1 = new ListBox();
listBox1.Dock = DockStyle.Bottom;
listBox1.Location = new Point(10, 10);
this.Controls.Add(listBox1);
}
static void Main()
{
// Создаем и запускаем новый экземпляр класса
Application.Run(new XmlRetriever());
}
// Обработчик события, срабатывающий при нажатии кнопки
void Button1_Click(object sender, EventArgs e)
{
XmlNodeList xmlNodes;
XmlNode xmlElement;
string elementValue;
// Используем охраняемый блок try-catch,
// что позволит в случае ошибок в выражениях XPath
// перехватывать обработку исключений, выдавать сообщение
// об ошибке и нормально продолжить работу приложения
try
{
// Выбираем из XML-документа элементы, которые соответствуют
// выражению XPath, заданному выбранным элементом ComboBox
xmlNodes = xmlDoc.SelectNodes(comboBox1.Text);
// Производим циклический перебор найденных элементов,
// добавляя каждый элемент в ListBox
listBox1.Items.Clear();
for (int i = 0; i < xmlNodes.Count; i++)
{
xmlElement = xmlNodes[i];
if (xmlElement.HasChildNodes)
{
elementValue = xmlElement.FirstChild.Value.Trim();
listBox1.Items.Add(elementValue);
}
}
}
catch (XPathException ex)
{
const string errorMessage =
"Ошибка в задании выражения XPath!" +
"\r\n" + "Соответствующие данные в документе не найдены!" +
"\r\n" + "Попробуйте задать другое выражение!";
MessageBox.Show(errorMessage +"\r\n" + ex.Message);
}
}
}
Программа отображает исходный XML-файл в элементе управления RichTextBox. Далее из списка элементов ComboBox можно выбрать одно из выражений и нажать на ListBox будут выведены элементы Xml-документа, заданные выражением . Вы можете задать собственное выражение в элементе ComboBox. После запуска программы поэкспериментируйте с вводом и выбором выражения , после чего нажмите кнопку "Получить данные".
Большинство приложений работают с базами данных. Любой программист из крупной компании подтвердит, что роль баз данных в мире вычислительных технологий очень велика. Обладая умением оперировать с базами данных, можно создавать самые разнообразные и действительно полезные приложения.
Возможно, у вас на компьютере уже установлена система управления базами данных, например, Microsoft Access. Лучшая альтернатива – это Microsoft SQL Server Express Edition, с помощью которого вы научитесь работать с базами данных SQL Server, используемыми во многих крупнейших компаниях по всему миру. SQL Server Express включен в пакет установки Visual C# Express, так что, скорее всего, на вашем компьютере он уже установлен.
Для работы с базами данных в библиотеке .NET Framework предусмотрены классы пространства имен System.Data. База данных в корне отличается от таких объектов, как изображения или документы текстовых редакторов, которые часто называют неструктурированными. Информация в базе данных структурирована и обычно хранится в таблицах, а каждая таблица состоит из строк и столбцов.
В программировании строки называют записями, а столбцы задают поля записи. Столбец таблицы определяет тип данных, хранимых в поле записи.
Ниже представлена таблица базы данных, содержащая информацию о планетах. Она имеет следующие столбцы: PlanetName (название планеты), DistanceFromSun (расстояние до Солнца) и Inhabitants (обитатели).
| PlanetName | DistanceFromSun (единица измерения – тысяча километров) | Inhabitants |
|---|---|---|
| Меркурий | 57909 | Меркуриане |
| Венера | 108200 | Венериане |
| Земля | 149600 | Земляне |
| Марс | 227940 | Марсиане |
| Юпитер | 778400 | Юпитериане |
| Знок | 7208100 | Знокиане |
| Сатурн | 1423600 | Сатурниане |
| Уран | 2867000 | Ураниане |
| Нептун | 4488400 | Нептуниане |
| Плутон | 5909600 | Плутониане |
Из таблицы видно, что, например, Венера находится на расстоянии 108 200 тысяч километров от Солнца, а существа, ее населяющие, называются венериане.
Вот еще одна таблица, в которой содержатся сведения о ежегодной численности обитателей разных планет.
Эта совершенно секретная информация, нигде ранее не обнародованная, была получена с инопланетного звездолета, потерпевшего крушение в самой глубине пустыни Гоби. Иметь возможность ознакомиться с ней – большая честь. Очевидно, представители инопланетной цивилизации тоже используют базы данных SQL Server, что и позволило нам привести эти сведения в качестве примера.
| PlanetName | Year | |
|---|---|---|
| Меркурий | 2008 | 40000 |
| Венера | 2008 | 25 |
| Земля | 2008 | 6000000000 |
| Марс | 2008 | 450000 |
| Юпитер | 2008 | 8326300200 |
| Знок | 2008 | 325000 |
| Сатурн | 2008 | 1000000 |
| Уран | 2008 | 7849345700 |
| Нептун | 2008 | <NULL> |
| Плутон | 2008 | <NULL> |
| Меркурий | 2009 | 35000 |
| Венера | 2009 | 3 |
| Земля | 2009 | 6500000000 |
| Марс | 2009 | 326800 |
| Юпитер | 2009 | 8451780500 |
| Знок | 2009 | 8700 |
| Сатурн | 2009 | 750000 |
| Уран | 2009 | 8237456000 |
| Нептун | 2009 | <NULL> |
| Плутон | 2009 | <NULL> |
Если продолжить разговор о Венере, то, обратите внимание, что в 2008 г. на Венере обитало 25 венериан, а через год, вероятно, в результате извержений вулканов, их осталось всего трое.
Не следует путать базы данных с электронными таблицами. Хотя способ представления данных в электронных таблицах внешне похож на тот, что использовался в приведенных выше примерах, обработка данных происходит в них иначе.
Существует множество разнообразных систем управления базами данных: Microsoft Access, Oracle,
Проще всего включить в код C# фрагмент на "языке базы данных", с помощью которого выполняется запрос к базе данных на получение нужных столбцов и строк.
(По правде говоря, существует еще и промежуточный уровень – ADO.NET, но сейчас мы не станем заострять на нем внимание.)
Много лет назад специалисты по базам данных договорились об использовании "единого языка баз данных", который понимали бы большинство существующих баз данных. Они назвали его SQL (от англ. Structured

Приступая к разговору о том, как использовать C# при работе с базами данных, сначала познакомимся с основами языка SQL. Ниже приведены примеры операторов на языке SQL и описывается результат их выполнения.
Основными командами SQL являются:
Приведем примеры каждой команды.
Как правило, оператор SELECT записывается следующим образом:
SELECT <имена извлекаемых столбцов> FROM <имена одной или нескольких таблиц базы данных> WHERE <условие выбора>
Рассмотрим пример выбора данных оператором SELECT:
SELECT * FROM PLANET
Символ звездочка * означает выбор всех столбцов таблицы. Поэтому данный оператор вернет из базы данных всю таблицу Planet со всеми строками и столбцами.
Рассмотрим оператор
SELECT PlanetName, Inhabitants FROM PLANET
Этот запрос возвращает столбцы PlanetName и Inhabitants со всеми строками из таблицы PLANET.
| PlanetName | Inhabitants |
|---|---|
| Меркурий | Меркуриане |
| Венера | Венериане |
| Земля | Земляне |
| Марс | Марсиане |
| Юпитер | Юпитериане |
| Знок | Знокиане |
| Сатурн | Сатурниане |
| Уран | Ураниане |
| Нептун | Нептуниане |
| Плутон | Плутониане |
Запрос
SELECT PlanetName, Inhabitants FROM PLANET WHERE PlanetName='Венера'
возвращает столбцы PlanetName и Inhabitants из таблицы PLANET. В результат его выполнения будут включены только те строки, которые содержат значение Венера в столбце PlanetName.
| PlanetName | Inhabitants |
|---|---|
| Венера | Венериане |
Запрос:
SELECT PlanetName, Population FROM POPULATION WHERE Population<100000
возвращает из таблицы строки столбцов PlanetName и , для которых значение столбца меньше 100000.
| PlanetName | |
|---|---|
| Меркурий | 40000 |
| Венера | 25 |
| Нептун | <NULL> |
| Плутон | <NULL> |
| Меркурий | 35000 |
| Венера | 3 |
| Знок | 8700 |
| Нептун | <NULL> |
| Плутон | <NULL> |
Как правило, оператор INSERT записывается следующим образом:
INSERT INTO <таблица базы данных, к которой добавляются строки> (<названия столбцов, в которые будут добавляться значения>) VALUES (<значения, которые будут вставлены в указанные столбцы>)
Пример:
INSERT INTO PLANET (PlanetName, DistanceFromSun, Inhabitants) VALUES (Флафф, 23500000, 'Флаффиане')
Оператор INSERT добавляет в таблицу PLANET новую строку. Он не возвращает какого-либо результата в программу, но после его выполнения таблица примет вот такой вид:
| PlanetName | DistanceFromSun | Inhabitants |
|---|---|---|
| Меркурий | 57909 | Меркуриане |
| Венера | 108200 | Венериане |
| Земля | 149600 | Земляне |
| Марс | 227940 | Марсиане |
| Юпитер | 778400 | Юпитериане |
| Знок | 7208100 | Знокиане |
| Сатурн | 1423600 | Сатурниане |
| Уран | 2867000 | Ураниане |
| Нептун | 4488400 | Нептуниане |
| Плутон | 5909600 | Плутониане |
| Флафф | 23500000 | Флаффиане |
Оператор UPDATE записывается следующим образом:
UPDATE <таблица базы данных, в которую вносятся изменения> SET <названия столбцов, в которые необходимо внести изменения> = <новые значения> WHERE <условия>
Пример:
UPDATE PLANET SET PlanetName= 'Стафф', Inhabitants='Стаффиане' WHERE PlanetName='Флафф'
Оператор изменяет некоторые значения в той строке, где столбец PlanetName имеет значение "Флафф". Результат выполнения операции программе не возвращается, но таблица примет вот такой вид:
| PlanetName | DistanceFromSun | Inhabitants |
|---|---|---|
| Меркурий | 57909 | Меркуриане |
| Венера | 108200 | Венериане |
| Земля | 149600 | Земляне |
| Марс | 227940 | Марсиане |
| Юпитер | 778400 | Юпитериане |
| Знок | 7208100 | Знокиане |
| Сатурн | 1423600 | Сатурниане |
| Уран | 2867000 | Ураниане |
| Нептун | 4488400 | Нептуниане |
| Плутон | 5909600 | Плутониане |
| Стафф | 23500000 | Стаффиане |
Если рассмотреть таблицы внимательно, то можно заметить, что между таблицами PLANET и существует связь: и в той и в другой есть столбец с именем PlanetName, который связывает обе таблицы. Благодаря этой связи можно собрать всю информацию об определенной планете.
Например, можно выбрать из обеих таблиц все строки, касающиеся Венеры:
|
|
|||||||||||||||||||||
А затем объединить полученные данные в одну большую таблицу:
SELECT * FROM PLANET INNER JOIN POPULATION ON PLANET.PlanetName=POPULATION.planetName WHERE PlanetName='Венера'
| PLANETS_AND_POPULATION | ||||
|---|---|---|---|---|
| PlanetName | DistanceFromSun | Inhabitants | Year | |
| Венера | 108200 | Венериане | 2008 | 25 |
| Венера | 108200 | Венериане | 2009 | 3 |
При работе с определенной СУБД необходимо учитывать ее особенности. С этой целью вводится понятие "провайдер данных" – у каждой СУБД он свой. С точки зрения программиста провайдер данных — это набор классов, обеспечивающих связь с базой и осуществляющих доступ к данным. Так, например, за связь с базой данных Microsoft SQL Server отвечает класс
Программный код меняется в зависимости от того, с какой базой предстоит работать. Для демонстрации возможностей
Три варианта базы данных Planets помещены в каталог с именем databases. Файлы Planets.mdf и Planets.ldf, задают базу данных SQL Server, файл Planets.accdb создан для базы данных Access 2007, а Planets.
В программном коде указывается путь к файлам базы данных, поэтому папка databases должна находиться в том же каталоге, где находится программа, задающая решение, — в нашем случае это файл Examples.sln.
При работе с базой данных SQL Server программный код зависит от того, с какой версией СУБД приходится работать — с Microsoft SQL Server или Microsoft SQL Server Express Edition.
В приведенном ниже примере показаны четыре возможных варианта работы:
Три варианта закомментированы, а один готов к использованию, в данном тексте это вариант работы с Microsoft SQL Server. В зависимости от того, что установлено на компьютере читателя, следует нужный вариант раскомментировать, а ненужный — закомментировать.
У большинства пользователей на компьютерах установлен комплект Microsoft Office, возможно, в нем имеется и приложение Access, так что для начала можно поработать с базами данных, подготовленными в этом приложении.
Когда вам понадобятся более широкие возможности программирования, мы рекомендуем вам установить SQL Server Express. К тому же умение работать с SQL Server гораздо выше ценится в деловой сфере, и чем скорее вы освоите этот инструмент, тем лучше. Загрузить его можно бесплатно с сайта Microsoft: http://www.microsoft.com/.
Далее в трех примерах программ на C# мы будем использовать классы Connection, Command, DataReader, DataAdapter. Префиксы Sql и OleDb указывают на то, с каким вариантом базы данных Planets мы работаем.
Пример программы 4.1
Следующая программа подключается к базе данных и посылает ей SQL-запрос. Затем выполняется несколько циклов получения результата запроса, после чего полученные результаты передаются в элемент управления ListBox и отображаются в списке.
using System.Windows.Forms;
using System.Data;
// Пространство имен для работы с базами данных SQL Server
using System.Data.SqlClient;
using System.Drawing;
// Пространство имен для работы с базами данных Access
using System.Data.OleDb;
class SimpleDataAccess : Form
{
public SimpleDataAccess()
{
// Указываем заголовок окна
this.Text = "Работа с базой данных. Чтение данных.";
// Добавляем элементы управления - метку и список
Label labelCaption = new Label();
labelCaption.Text = "Планеты солнечной системы!";
labelCaption.Location = new Point(30, 10);
labelCaption.Width = 200;
labelCaption.Parent = this;
ListBox listPlanets = new ListBox();
listPlanets.Location = new Point(30, 50);
listPlanets.Width = 100;
listPlanets.Parent = this;
// Формируем запрос к базе данных -
//запрашиваем информацию о планетах
string sql = "SELECT * FROM PLANET";
string connectionString;
/*
//Вариант 1
// Подключаемся к базе данных SQL Server Express Edition
// Указываем физический путь к базе данных PLANETS
string dbLocation =
("../../../databases/planets.mdf");
connectionString = @"data source=.\SQLEXPRESS;" +
"User Instance=true;Integrated Security=SSPI;" +
"AttachDBFilename=" + dbLocation;
SqlConnection connection1 = new SqlConnection(connectionString);
*/
//Вариант 2
// Подключаемся к базе данных SQL Server 2005
connectionString =
"data source = localhost; Initial Catalog = Planets;" +
"Integrated Security = SSPI";
SqlConnection connection1 = new SqlConnection(connectionString);
//Открываем соединение
connection1.Open();
SqlCommand command1 = new SqlCommand(sql, connection1);
SqlDataReader dataReader1 = command1.ExecuteReader();
// Организуем циклический перебор полученных записей
//и выводим название каждой планеты в список
while (dataReader1.Read())
{
listPlanets.Items.Add(dataReader1["PlanetName"]);
}
// Очистка
dataReader1.Close();
connection1.Close();
/*
//Вариант 3. Связывание с базой данных Access 2003 - *.mdb
connectionString = "Provider=Microsoft.Jet.OLEDB.4.0;" +
@"Data Source= ../../../databases/planets.mdb";
//Вариант 4. Связывание с базой данных Access 2007 - *.accdb
connectionString = "Provider=Microsoft.Ace.OLEDB.12.0;" +
@"Data Source= ../../../databases/planets.accdb";
OleDbConnection connection = new OleDbConnection(connectionString);
connection.Open();
OleDbCommand command = new OleDbCommand(sql, connection);
OleDbDataReader dataReader = command.ExecuteReader();
// Организуем циклический перебор полученных записей
//и выводим название каждой планеты в список
while (dataReader.Read())
{
listPlanets.Items.Add(dataReader["PlanetName"]);
}
// Очистка
dataReader.Close();
connection.Close();
* */
}
static void Main()
{
// Создаем и запускаем форму
Application.Run(new SimpleDataAccess());
}
}

Пример программы 4.2
В этой программе на экран выводится несколько столбцов данных. Для их представления мы воспользуемся элементом DataGridView.
Программа выполняет тот же запрос, что и в предыдущем примере, но помещает результат в объект , который подключается к элементу управления DataGridView, а тот автоматически отображает все данные.
Подключение источника данных к визуальному элементу управления называется привязкой, или связыванием данных.
using System.Windows.Forms;
using System.Data;
// Пространство имен для работы с базами данных SQL Server
using System.Data.SqlClient;
using System.Drawing;
// Пространство имен для работы с базами данных Access
using System.Data.OleDb;
class DataInGrid : Form
{
public DataInGrid()
{
//Изменяем размеры формы
this.Width = 450;
this.Height = 400;
// Указываем заголовок окна
this.Text = "Одностороннее связывание:" +
" база данных и элемент Grid.";
// Добавляем элементы управления - метку и таблицу
Label labelCaption = new Label();
labelCaption.Text = "Планеты солнечной системы!";
labelCaption.Location = new Point(60, 10);
labelCaption.Width = 200;
labelCaption.Parent = this;
// Добавляем элемент DataGridView на форму
DataGridView dataGridView1 = new DataGridView();
dataGridView1.Width = 350;
dataGridView1.Height = 250;
dataGridView1.Location = new Point(20, 50);
dataGridView1.DataMember = "Table";
dataGridView1.AutoResizeColumns();
this.Controls.Add(dataGridView1);
// Формируем запрос к базе данных -
//запрашиваем информацию о планетах
string sql = "SELECT * FROM PLANET";
string connectionString;
// DataSet сохраняет данные в памяти
//данные хранятся в виде таблиц данных DataTable
DataSet dataSet1 = new DataSet();
/*
//Вариант 1
// Подключаемся к базе данных SQL Server Express Edition
// Указываем физический путь к базе данных PLANETS
string dbLocation =
("../../../databases/planets.mdf");
connectionString = @"data source=.\SQLEXPRESS;" +
"User Instance=true;Integrated Security=SSPI;" +
"AttachDBFilename=" + dbLocation;
SqlConnection connection1 = new SqlConnection(connectionString);
*/
/*
//Вариант 2
// Подключаемся к базе данных SQL Server 2005
connectionString =
"data source = localhost; Initial Catalog = Planets;" +
"Integrated Security = SSPI";
SqlConnection connection1 = new SqlConnection(connectionString);
//Открываем соединение
connection1.Open();
// DataAdapter - посредник между базой данных и DataSet
SqlDataAdapter sqlDataAdapter1 = new SqlDataAdapter();
// Создаем объект DataAdapter,
//передаем ему данные запроса
sqlDataAdapter1.SelectCommand =
new SqlCommand(sql, connection1);
// Данные из адаптера поступают в DataSet
sqlDataAdapter1.Fill(dataSet1);
// Связываем данные с элементом DataGridView
DataGridView1.DataSource = dataSet1;
// Очистка
connection1.Close();
* */
/*
//Вариант 3. Связывание с базой данных Access 2003 - *.mdb
connectionString = "Provider=Microsoft.Jet.OLEDB.4.0;" +
@"Data Source= ../../../databases/planets.mdb";
*/
//Вариант 4. Связывание с базой данных Access 2007 - *.accdb
connectionString = "Provider=Microsoft.Ace.OLEDB.12.0;" +
@"Data Source= ../../../databases/planets.accdb";
OleDbConnection connection = new OleDbConnection(connectionString);
connection.Open();
OleDbDataAdapter dataAdapter = new OleDbDataAdapter();
dataAdapter.SelectCommand = new OleDbCommand(sql, connection);
dataAdapter.Fill(dataSet1);
dataGridView1.DataSource = dataSet1;
// Очистка
connection.Close();
}
static void Main()
{
// Создаем и запускаем форму
Application.Run(new DataInGrid());
}
}

Пример программы 4.3
Научившись отображать данные с помощью элемента управления DataGridView, вы, наверное, обратили внимание, что внесенные в базу изменения не сохраняются. Поэтому применим другой подход и осуществим "двухстороннюю привязку данных", которая позволит не только просматривать открывшуюся таблицу, но и вводить изменения в элемент DataGridView, добавляя новые строки, изменяя содержимое имеющихся строк и удаляя ненужные. Объекты класса DataAdapter способны выполнять как операцию Select, получая данные запроса из базы данных, так и команды Insert, Update, Delete, изменяя содержимое таблицы базы данных.
Здесь мы позволим себе маленькую хитрость (это называется "повысить производительность труда") и не станем самостоятельно прописывать операторы UPDATE и INSERT. Пространство имен System.Data содержит небольшой, но очень полезный класс CommandBuilder, который умеет создавать команды SQL и автоматически их выполнять.
using System;
using System.Windows.Forms;
using System.Data;
// Пространство имен для работы с базами данных SQL Server
using System.Data.SqlClient;
using System.Drawing;
using System.Diagnostics;
class DataInOutGrid: Form
{
SqlDataAdapter dataAdapter;
DataGridView dataGridView;
public DataInOutGrid()
{
//Изменяем размеры формы
this.Width = 450;
this.Height = 400;
// Указываем заголовок окна
this.Text = "Двустороннее связывание:" +
" база данных и элемент Grid.";
// Добавляем элементы управления -
//метку, таблицу и командную кнопку
Label labelCaption = new Label();
labelCaption.Text = "Планеты!";
labelCaption.Location = new Point(60, 10);
labelCaption.Width = 200;
labelCaption.Parent = this;
// Добавляем элемент DataGridView на форму
dataGridView = new DataGridView();
dataGridView.Width = 350;
dataGridView.Height = 250;
dataGridView.Location = new Point(20, 50);
dataGridView.AutoResizeColumns();
this.Controls.Add(dataGridView);
// Добавляем командную кнопку
Button buttonSave = new Button();
buttonSave.Location = new Point(100, 320);
buttonSave.Width = 220;
buttonSave.Text = "Сохранить изменения в базе данных!";
buttonSave.Click +=
new System.EventHandler(ButtonSave_Click);
buttonSave.Parent = this;
// Формируем запрос к базе данных -
//запрашиваем информацию о планетах
string sql = "SELECT * FROM PLANET";
string connectionString;
// DataTable сохраняет данные в памяти как таблицу
DataTable dataTable = new DataTable();
/*
//Вариант 1
// Подключаемся к базе данных SQL Server Express Edition
// Указываем физический путь к базе данных PLANETS
string dbLocation =
("../../../databases/planets.mdf");
connectionString = @"data source=.\SQLEXPRESS;" +
"User Instance=true;Integrated Security=SSPI;" +
"AttachDBFilename=" + dbLocation;
SqlConnection connection1 = new SqlConnection(connectionString);
*/
//Вариант 2
// Подключаемся к базе данных SQL Server 2005
connectionString =
"data source = localhost; Initial Catalog = Planets;" +
"Integrated Security = SSPI";
SqlConnection connection = new SqlConnection(connectionString);
//Открываем соединение
connection.Open();
//Создаем команду
SqlCommand sqlCommand = new SqlCommand(sql, connection);
//Создаем адаптер
// DataAdapter - посредник между базой данных и DataSet
dataAdapter = new SqlDataAdapter(sqlCommand);
//Создаем построитель команд
//Для адаптера становится доступной команда Update
SqlCommandBuilder commandBuilder =
new SqlCommandBuilder(dataAdapter);
// Данные из адаптера поступают в DataTable
dataAdapter.Fill(dataTable);
// Связываем данные с элементом DataGridView
dataGridView.DataSource = dataTable;
// Очистка
connection.Close();
}
static void Main()
{
// Создаем и запускаем форму
Application.Run(new DataInOutGrid());
}
void ButtonSave_Click(object sender, System.EventArgs args)
{
try
{
dataAdapter.Update((DataTable)dataGridView.DataSource);
MessageBox.Show("Изменения в базе данных выполнены!",
"Уведомление о результатах", MessageBoxButtons.OK);
}
catch(Exception)
{
MessageBox.Show("Изменения в базе данных выполнить не удалось!",
"Уведомление о результатах", MessageBoxButtons.OK);
}
}
}
На следующем рисунке показано содержимое базы данных, в которую добавлены две строки с названиями недавно открытых фантастических планет Солярис и Обитаемый остров (или коротко – Остров).

Поэкспериментируйте, изменяя существующие значения и вводя новые. Нажмите кнопку "Сохранить изменения" и закройте форму. Перезапустив программу, убедитесь, что все значения были сохранены в базе данных. Если вы работаете с Access, то измените код в соответствии с образцом, приведенным в программах Example 12 и Example 13.
Классы пространства имен System.Xml позволяют работать с XML-данными разными способами. Наиболее часто выполняются следующие задачи:
Язык XML (от англ. eXtensible Markup Language – расширяемый язык разметки) предназначен для хранения структурированных данных. Данные, хранящиеся в формате XML, можно передавать между программами. Поскольку данные в XML структурированные, в некоторых случаях использование этого формата может заменить базы данных. Кроме этого, у XML есть еще много других полезных применений.
Язык XML широко распространен, и, скорее всего, вы уже слышали о нем. Этот язык удобно воспринимать как человеку, так и машине. Большая часть программного кода, с которыми работают различные вычислительные системы, обычным людям кажутся китайской грамотой, но XML-документы записываются почти как обычный текст.
Например, можно составить XML-документ для хранения на диске географических данных:
<?xml version="1.0" encoding="utf-8" ?>
-<Планета>
Земля
- <Континент>
Южная Америка
<Страна столица="Рио-де-Жанейро">
Бразилия
</Страна>
<Страна столица="Буэнос-Айрес">
Аргентина
</Страна>
</Континент>
- <Континент>
Азия
<Страна столица="Дели">
Индия
</Страна>
<Страна столица="Бангкок">
Тайланд
</Страна>
</Континент>
</Планета>
|
Каждый XML-документ начинается со строки <?xml version="1.0" encoding="utf-8" ?>. Встретив такую строку, программа будет знать, что имеет дело именно с XMLСтроки заключенные в треугольные скобки ( Внешний блок Планета Блоки более глубокого уровня вложения, содержат информацию о странах данного континента Еще один |
XML весьма похож на другой язык разметки HTML, но в HTML набор тегов фиксирован, и у каждого тега есть свое строго определенное назначение и правила написания. В XML можно определять собственные теги, но при этом все равно нужно соблюдать синтаксические правила языка разметки.
Далее мы обсудим значение двух терминов, без знания которых невозможно дальнейшее изучение языка XML.
XML-документ - это запись, состоящая из отдельных элементов. Каждый элемент начинается с открывающего тега, заключенного в треугольные скобки ( <> ) – и заканчивается закрывающим тегом ( </> ).
Имя элемента задается в открывающем теге и повторяется в закрывающем теге, а между открывающим и закрывающим тегами находится его содержание. В содержание тега могут быть вложены другие теги. Теги с одним именем нередко повторяются, даже если они не вложены один в другой.
В приведенном выше XML-документе один из элементов с именем <Континент> имеет значение "Южная Америка". В него вложены два элемента с именем <Страна>, содержательно задающие названия стран этого континента.
| Имя элемента в открывающем теге | Значение | Закрывающий тег |
|---|---|---|
| <Страна> | Бразилия | </Страна> |
| <Школьник> | Ваня Курочкин | </Школьник> |
В открывающем теге можно задавать дополнительные свойства элемента. Для этого используются атрибуты. Каждый атрибут задается парой "имя = "значение"". Например, если для элемента <Страна> надо указать столицу, то можно создать атрибут элемента с именем "столица". А для элемента <Школьник> задать атрибуты "возраст" и "класс". В приведенном ниже примере у элемента "Страна" со значением "Аргентина" атрибут "столица" имеет значение "Буэнос-Айрес".
| Открывающий тег | Значение элемента | Закрывающий тег | ||||
|---|---|---|---|---|---|---|
| Имя элемента | Имя атрибута | Значение атрибута | ||||
<Страна |
столица |
= |
"Буэнос-Айрес" |
> |
Аргентина |
</Страна> |
Читать подобные документы не составляет труда, а поскольку они имеют четкую структуру, то и компьютер можно научить этому без особых проблем. Например, составить такой набор инструкций: "Начать просмотр документа; при нахождении символа " < " — читать имя элемента. При нахождении символа " > " — читать значение элемента..." и так далее.
Некоторые элементы могут иметь только атрибуты и не иметь значения и содержания. Тогда открывающий и закрывающий теги объединяются. Например, элемент <Страна> можно задать следующим образом:
<Страна название = "Аргентина" столица = "Буэнос-Айрес" />
Для описания элемента использовались два атрибута, но не значение элемента.
Пример программы 4.4
Следующая программа считывает данные из XML-файла и отображает их на форме.
В ней используются три класса из пространства имен System.Xml:
XmlDocument. Объекты этого класса задают Xml-документ. При создании объекта содержимое документа может быть прочитано из файла, получено из других источников или создано в ходе работы программы.XmlNodeList. Объекты этого класса могут содержать некоторый список элементов XML-документа, найденный, например, в результате поиска.XmlNode. Объект этого класса задает один XML-элемент.Для поиска нужных фрагментов XML-документа в программе используются так называемые выражения . Они позволяют указать, какие именно элементы необходимо извлечь из XML-документа. Выражение вида "/континент/страна" означает: "найти все элементы с именем "страна", вложенные в элемент с именем "континент"".
using System;
using System.Windows.Forms;
using System.Drawing;
// Пространство имен для работы с XML-данными
using System.Xml;
//Пространство имен для работы с выражениями xPath
using System.Xml.XPath;
class XmlRetriever: Form
{
ComboBox comboBox1;
Button button1;
ListBox listBox1;
RichTextBox richTextBox1;
XmlDocument xmlDoc;
// Метод-конструктор нашего класса
public XmlRetriever()
{
// Задаем заголовок и размеры окна
this.Text = "Работа с XML-документом";
this.Size = new Size(400, 400);
// Создаем объект XmlDocument, используя xml-файл
xmlDoc = new XmlDocument();
xmlDoc.Load("../../docs/Planets.xml");
// Создаем объект TextBox для вывода данных
richTextBox1 = new RichTextBox();
richTextBox1.Dock = DockStyle.Top;
richTextBox1.AcceptsTab = true;
richTextBox1.Height = 180;
richTextBox1.ReadOnly = true;
richTextBox1.BackColor = Color.Silver;
// Помещаем XML-данные в элемент TextBox
richTextBox1.Text = xmlDoc.OuterXml;
this.Controls.Add(richTextBox1);
// Создаем объект ComboBox
// В элементы списка этого объекта записываем
//различные выражения XPath,
//позволяющие искать нужные элементы XML-документа
comboBox1 = new ComboBox();
comboBox1.Location = new Point(0, 200);
comboBox1.Width = 300;
comboBox1.Items.Add("/Планета");
comboBox1.Items.Add("/Планета/Континент");
comboBox1.Items.Add("/Планета/Континент/Страна");
comboBox1.Items.Add(
"/Планета/Континент/Страна[@столица='Рио-де-Жанейро']");
comboBox1.SelectedIndex = 0;
this.Controls.Add(comboBox1);
// Создаем командную кнопку для поиска и отображения
// соответствующих элементов Xml-документа
button1 = new Button();
button1.Text = "Получить данные";
button1.Location = new Point(100, 230);
button1.Width = 120;
button1.Click += new EventHandler(Button1_Click);
this.Controls.Add(button1);
// Создаем элемент ListBox для отображения элементов
listBox1 = new ListBox();
listBox1.Dock = DockStyle.Bottom;
listBox1.Location = new Point(10, 10);
this.Controls.Add(listBox1);
}
static void Main()
{
// Создаем и запускаем новый экземпляр класса
Application.Run(new XmlRetriever());
}
// Обработчик события, срабатывающий при нажатии кнопки
void Button1_Click(object sender, EventArgs e)
{
XmlNodeList xmlNodes;
XmlNode xmlElement;
string elementValue;
// Используем охраняемый блок try-catch,
// что позволит в случае ошибок в выражениях XPath
// перехватывать обработку исключений, выдавать сообщение
// об ошибке и нормально продолжить работу приложения
try
{
// Выбираем из XML-документа элементы, которые соответствуют
// выражению XPath, заданному выбранным элементом ComboBox
xmlNodes = xmlDoc.SelectNodes(comboBox1.Text);
// Производим циклический перебор найденных элементов,
// добавляя каждый элемент в ListBox
listBox1.Items.Clear();
for (int i = 0; i < xmlNodes.Count; i++)
{
xmlElement = xmlNodes[i];
if (xmlElement.HasChildNodes)
{
elementValue = xmlElement.FirstChild.Value.Trim();
listBox1.Items.Add(elementValue);
}
}
}
catch (XPathException ex)
{
const string errorMessage =
"Ошибка в задании выражения XPath!" +
"\r\n" + "Соответствующие данные в документе не найдены!" +
"\r\n" + "Попробуйте задать другое выражение!";
MessageBox.Show(errorMessage +"\r\n" + ex.Message);
}
}
}
Программа отображает исходный XML-файл в элементе управления RichTextBox. Далее из списка элементов ComboBox можно выбрать одно из выражений и нажать на ListBox будут выведены элементы Xml-документа, заданные выражением . Вы можете задать собственное выражение в элементе ComboBox. После запуска программы поэкспериментируйте с вводом и выбором выражения , после чего нажмите кнопку "Получить данные".
Для получения официальных документов о завершении программы дополнительного профессионального образования (удостоверения о повышении квалификации, дипломов о профессиональной переподготовке и MBA) необходимо предоставить:
Внимание! Вы можете не заказывать доставку бумажной версии официального документы, а скачать его в электронном виде и распечатать самостоятельно. Информация о выданном документе в течение 1 месяца загружается в Федеральную информационную систему «Федеральный реестр сведений о документах об образовании и (или) о квалификации, документах об обучении» - ФИС ФРДО.
Доступ на новый сайт осуществляется с использованием адреса электронной почты, который был указан вами при регистрации на "старом". Мы постарались перенести все ваши данные с прежнего ресурса, однако не исключена вероятность потери части информации.
При возникновении проблемы со входом, воспользуйтесь функцией сброса пароля
Если вы обнаружите несоответствия, пожалуйста, сообщите нам.