AddNode(id);
UpdateTree();
Рассмотрим реализацию метода AddNode, служащего для добавления нового узла в дереве заголовков статей и добавления всех необходимых записей в базу данных Articles:
public void AddNode(int id)
{
Form2 dialog = new Form2();
if (DialogResult.Yes == dialog.ShowDialog())
{
sqlConnection1.Open();
try
{
SqlCommand cmd = new SqlCommand("sp_InsertNode",sqlConnection1);
cmd.CommandType = CommandType.StoredProcedure;
SqlParameter param = cmd.Parameters.Add("RETURN_VALUE",SqlDbType.Int);
param.Direction = ParameterDirection.ReturnValue;
cmd.Parameters.Add("@parent_id", SqlDbType.Int).Value = id;
cmd.Parameters.Add("@title", SqlDbType.VarChar).Value =dialog.Title;
cmd.Parameters.Add("@weight", SqlDbType.Int).Value =dialog.Weight;
cmd.ExecuteNonQuery();
int tree_id = (int)cmd.Parameters["RETURN_VALUE"].Value;
cmd = new SqlCommand("sp_InsertDocument", sqlConnection1);
cmd.CommandType = CommandType.StoredProcedure;
param = cmd.Parameters.Add("RETURN_VALUE", SqlDbType.Int);
param.Direction = ParameterDirection.ReturnValue;
cmd.Parameters.Add("@tree_id", SqlDbType.Int).Value = tree_id;
cmd.Parameters.Add("@document", SqlDbType.Text).Value =dialog.Document;
cmd.ExecuteNonQuery();
int document_id = (int)cmd.Parameters["RETURN_VALUE"].Value;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка");
}
sqlConnection1.Close();
}
}
В самом начале работы метод AddNode отображает диалоговое окно для добавления новой статьи. Это диалоговое окно представляет собой класс Form2, добавленный непосредственно в проект приложения ArticlesApp.
Если пользователь завершил работу с данным диалоговым окном нажатием кнопки Сохранить, то метод AddNode извлекает данные, введённые пользователем и добавляет их в таблицы базы данных Articles:
Form2 dialog = new Form2();
if (DialogResult.Yes == dialog.ShowDialog())
{
...
Для добавления данных, прежде всего, открывается соединение с базой данных: sqlConnection1.Open();
Все дальнейшие операции выполняются в теле оператора try-catch, что позволяет перехватывать ошибки и отображать текст сообщений об ошибках на экране:
try
{
...
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Ошибка");}
После обновления содержимого базы данных метод AddNode закрывает соединение с базой данных SqlConnection1.Close();.
3.5.2 Использование хранимых процедур
Прежде всего, моя программа вызывает хранимую процедуру sp_InsertNode, предназначенную для добавления новой строки в таблицу Tree, хранящую структуру дерева. Напомню, что этой процедуре нужно передать через входные параметры идентификатор родительского узла @parent_id, заголовок статьи @title и вес сортировки @weight.
Вызов хранимой процедуры начинается с создания объекта класса SqlCommand:
SqlCommand cmd = new SqlCommand("sp_InsertNode",sqlConnection1);
cmd.CommandType = CommandType.StoredProcedure;
Далеепрограммадолжназадатьтипкомандывсвойстве CommandType ввидеконстанты CommandType.StoredProcedure: cmd.CommandType.
Это означает, что команда содержит не строку SQL, а имя хранимой процедуры.
На следующем этапе необходимо добавить параметры хранимой процедуры. Наша хранимая процедура sp_InsertNode имеет три входных и один выходной параметр.
Через выходной параметр со специальным именем RETURN_VALUE хранимая процедура возвращает идентификатор добавленной строки:
SqlParameter param = cmd.Parameters.Add("RETURN_VALUE",SqlDbType.Int);
В качестве первого параметра методу Add передается имя параметра хранимой процедуры, а в качестве второго — тип данных, соответствующих этому параметру.
Чтобы указать, что этот параметр является выходным, я записываю константу ParameterDirection.ReturnValue в свойство параметра с именем Direction:
param.Direction = ParameterDirection.ReturnValue;
Если этого не сделать, то по умолчанию параметр будет входным.
Вот как я указываю входные параметры для хранимой процедуры sp_InsertNode:
cmd.Parameters.Add("@parent_id", SqlDbType.Int).Value = id;
cmd.Parameters.Add("@title", SqlDbType.VarChar).Value =dialog.Title;
cmd.Parameters.Add("@weight", SqlDbType.Int).Value =dialog.Weight;
Следует отметить, что тип числовых данных указан как SqlDbType.Int, а тип строчных данных — как SqlDbType.VarChar.
Параметру хранимой процедуры @parent_id я присваиваю значение идентификатора родительского узла, который передается при вызове методу AddNode. Что же касается параметров @title и @weight, то для их инициализации я извлекаю значения из свойств Title и Weight, определенных мною в классе Form2 диалогового окна ввода данных узла.
Для запуска хранимой процедуры на выполнение вызывается метод ExecuteNonQuery:
cmd.ExecuteNonQuery();
Если у хранимой процедуры имеются параметры (как в моём случае), то их необходимо подготовить. Иначе при выполнении метода ExecuteNonQuery возникнет необработанное исключение.
После того как хранимая процедура завершит свою работу, программа может получить значение ее выходных параметров при помощи свойства Value.
Вот как я извлекаю значение, возвращаемое хранимой процедурой sp_InsertNode:
int tree_id = (int)cmd.Parameters["RETURN_VALUE"].Value;
Напомню, что моя хранимая процедура возвращает идентификатор узла, добавленного в таблицу Tree. Этот идентификатор понадобится нам в дальнейшем для инициализации ячейки внешнего ключа таблицы Documents, ссылающейся на таблицу Tree.
Для добавления текста документа, извлеченного из свойства dialog.Document диалогового окна класса Form2 я вызываю хранимую процедуру sp_InsertDocument:
cmd = new SqlCommand("sp_InsertDocument", sqlConnection1);
cmd.CommandType = CommandType.StoredProcedure;
param = cmd.Parameters.Add("RETURN_VALUE", SqlDbType.Int);
param.Direction = ParameterDirection.ReturnValue;
cmd.Parameters.Add("@tree_id", SqlDbType.Int).Value = tree_id;
cmd.Parameters.Add("@document", SqlDbType.Text).Value =dialog.Document;
cmd.ExecuteNonQuery();
int document_id = (int)cmd.Parameters["RETURN_VALUE"].Value;
Выходной параметр получает возможность получить идентификатор новой строки в таблице Documents. Я извлекаю его только для примера, но в приложении не использую. Что же касается входных параметров, то хранимой процедуре sp_InsertDocument передается идентификатор узла @tree_id обновляемой статьи, а также текст статьи @document.
Для того чтобы программа могла инициализировать поля формы, а также получать значения, введенные в ней пользователем, необходимо создать в классе Form2 свойства Title, Weight и Document с помощью полей set и get. Ниже приведены исходные коды для этих свойств:
public string Title
{
get
{
return textBox1.Text;
}
set
{
textBox1.Text = value;
}
}
public int Weight
{
get
{
return (int)numericUpDown1.Value;
}
set
{
numericUpDown1.Value = value;
}
}
public string Document
{
get
{
return richTextBox1.Text;
}
set
{
richTextBox1.Text = value;
}
}
Для построения дерева заголовков статей в окне элемента управления TreeView в нашем приложении определен метод UpdateTree, на который я уже ссылались ранее, а также метод CreateNodes.
Метод UpdateTree считывает структуру дерева из базы данных Articles и отображает ее в окне элемента управления treeView1 класса TreeView.
public void UpdateTree()
{
dataSet11.Clear();
sqlDataAdapter1.Fill(dataSet11);
treeView1.Nodes.Clear();
CreateNodes(0, (TreeNode)null);
}
Получивуправление, метод UpdateTree очищаетнаборданных dataSet11, азатемнаполняетегоизтаблицы Tree базыданных Aticles, пользуясьдляэтогоадаптером sqlDataAdapter1 иметодом Fill.Заполнение дерева treeView1 содержимым набора данных dataSet11 осуществляется методом CreateNodes.
public void CreateNodes(int iParent, TreeNode pNode)
{
DataView dvwData = new DataView(dataSet11.Tree);
dvwData.RowFilter = "[parent_id] = " + iParent;
foreach (DataRowView Row in dvwData)
{
int id = Int32.Parse(Row["id"].ToString());
if (pNode == null)
{
TreeNode zNode = treeView1.Nodes.Add(Row["title"].ToString() +
" (" + Row["weight"].ToString() + ")");
zNode.Tag = id;
CreateNodes(id, zNode);
}
else
{
if (id == iParent)
return;
TreeNode zNode = pNode.Nodes.Add(Row["title"].ToString() +
" (" + Row["weight"].ToString() + ")");
zNode.Tag = id;
CreateNodes(id, zNode);
}
}
}
Метод CreateNodes имеетдвапараметра.
Через первый параметр методу передается идентификатор узла, родительского по отношению к добавляемому узлу. Если создается корневой узел, то значение этого параметра равно нулю.
Второй параметр используется для передачи ссылки на родительский узел дерева treeView1, который является объектом класса TreeNode. При создании корневого узла этот параметр должен иметь значение null.
Прежде всего, он создает представление (view) таблицы dvwData, хранящейся в наборе данных dataSet11. Это представление включает в себя подмножество строк таблицы, столбец parent_id которых содержит идентификатор родительского узла, переданного методу CreateNodes в качестве первого параметра. Иными словами, здесь происходит отбор дочерних узлов заданного родительского узла.
база данных приложение microsoft
В настоящей курсовой работе были изложены сведения о платформе Microsoft.NETFramework, рассказано о способах и методах доступа к базам данных и системам управления базами данных, а также на конкретном примере продемонстрирована работа по проектированию и программированию баз данных средствами выше упомянутой платформы. Мною было спроектировано приложение «Articles», исходный код которого прилагается к курсовой работе.
В ходе выполнения данной курсовой я узнал много новых аспектов, касающихся программирования баз данных на языке C#, а также познакомился со способами работы MicrosoftSQLServer 2008. Считаю поставленную задачу полностью выполненной и реализованной.
Размещено на http://www.