Распределенная обработка данных и XML

Если нужно создать информационную систему с распределенной обработкой данных, встает вопрос организации взаимодействия между серверами и клиентами такой системы. Метод доступа ADO позволяет организовать такую обработку средствами COM, однако этот способ имеет определенные недостатки. Эти недостатки проявляются в тех случаях, когда нужно объединить узлы системы при помощи каналов Интернета.

Дело в том, что корпоративные интрасети, подключенные к Интернету, обычно защищаются брандмауэром (firewall), открывающим доступ только для определенных портов TCP/IP и для определенных протоколов передачи данных. Обычно открывается только порт 80, предназначенный для работы с Web-серверами посредством протокола HTTP, а также порты протоколов SMTP, POP3 и IMAP, с помощью которых осуществляется передача электронной почты. Эти ограничения обычно несовместимы с системами удаленной обработки, реализованными с использованием модели COM.

Что же касается ADO.NET, то этот метод доступа допускает представление данных в формате XML. При этом данные могут передаваться с использованием протокола HTTP, что позволяет объединять информационные системы каналами Интернета, даже если эти системы защищены брандмауэрами.

 

Провайдеры данных для управляемого кода

Программный компонент, называемый провайдером данных (data provider) выступает в качестве моста между приложением и источником данных. В его задачу входит извлечение данных из источника, а также обновление источника данных.

Для приложений, содержащих управляемый код и предназначенных для платформы Microsoft.NET, компания Microsoft разработала три провайдера данных. Это SQL Server.NET Data Provider, OLE DB.NET Data Provider и ODBC.NET Data Provider. Первые два из них входят в состав среды исполнения Microsoft.NET Framework, а третий можно загрузить с Web-сайта компании Microsoft по адресу http://msdn.microsoft.com/downloads.

Если приложение C# должно работать с сервером Microsoft SQL Server версии 7.0 или более новой версии, максимальная производительность будет достигнута при использовании провайдера данных SQL Server.NET Data Provider. К сожалению, специализированных провайдеров для прямого доступа из управляемого кода к СУБД других типов пока не существует.

Что же касается провайдера OLE DB.NET Data Provider, то он пригодится Вам для доступа к базам данных Microsoft Access и другим СУБД, для которых реализованы провайдеры OLE DB.

В том случае, когда единственно возможный способ интеграции приложения и СУБД заключается в использовании драйвера ODBC, можно воспользоваться провайдером ODBC.NET Data Provider.



Глава 3. Проектирование и разработка базы данных «Статьи»

Спецификация проекта

 

Очень часто возникает необходимость в хранении информации иерархического вида. Реляционные СУБД, такие как Microsoft SQL Server, позволяют хранить информацию в виде иерархического дерева, причем для представления такого дерева нужна всего одна таблица.

Каждая строка таблицы, хранящей структуру дерева, соответствует одному узлу этого дерева. При этом в таблице должно быть, как минимум, два столбца. Первый из них должен содержать уникальные идентификаторы строки (т.е. идентификаторы узлов), а второй — идентификатор соответствующего родительского узла. Для корневого узла в качестве идентификатора родительского узла обычно используется нулевое или какое-либо другое особое значение.

Для демонстрации способа хранения дерева в базе данных, а также для того, чтобы на конкретном примере изучить некоторые новые для меня методы работы с базами данных в приложениях C#, я разработал приложение ArticlesApp.

Приложение ArticlesApp представляет собой простейшую информационную систему, предназначенную для хранения текстовой информации. В базе данных этой системы Articles хранятся статьи, организованные иерархическим образом.

В левой части этого окна имеется дерево, созданное с использованием элемента управления TreeView. Окно этого дерева отображает заголовки статей, а также так называемые веса сортировки заголовков, указанные в круглых скобках. Эти веса понадобятся мне далее в программе для корректного отображения иерархичности данных.

Замечу, что сразу после запуска приложения, когда в базе данных нет ни одной записи, дерево заголовков не содержит ни одного элемента. Если щелкнуть окно дерева правой клавишей мыши, на экране появится контекстное меню со строками Добавить статью, Удалить статью и Правка статьи. При нажатии на эти кнопки вызываются методы, позволяющие управлять содержимым базы данных.

Выбор строки Добавить статью приведет к тому, что на экране появится диалоговое окно Form2, специально созданное для этой цели. Оно содержит поле типа textbox для хранения заголовка статьи, поле типа RichTextBox для хранения самого текста статьи. Также имеется поле типа numericUpDown для хранения веса сортировки и 2 кнопки Сохранить и Отменить. Таким образом, при помощи этого окна можно добавить в базу данных новую статью, определив для нее заголовок, тело и вес сортировки.

Если в дереве нет ни одного элемента, то при первом использовании строки Добавить статью контекстного меню в дерево будет добавлен корневой элемент. Для того чтобы добавить в дерево дочерний элемент, нужно вначале выделить левой клавишей мыши заголовок родительского элемента, а потом, щелкнув этот заголовок правой клавишей мыши, выбрать из контекстного меню строку Добавить статью. Редактирование любого элемента выполняется аналогично. Для выполнения этой операции нужно выделить элемент, а затем, щелкнув его правой клавишей мыши, выбрать из контекстного меню строку Правка статьи. С помощью строки Удалить статью можно удалить элемент дерева. Замечу, что программа удаляет только элементы, не имеющие дочерних элементов. Попытки удалить элемент с дочерними элементами моё приложение игнорирует.

 

База данных Articles

 

Для создания приложения ArticlesApp мною была создана база данных Articles на Microsoft SQL Server 2008. Она содержит 2 таблицы и 3 хранимые процедуры.

Таблица Tree предназначена для хранения структуры дерева статей. В ней создано четыре столбца с именами id, parent_id, title и weight. Столбец id является первичным ключом. Данную таблицу я создал с помощью sql-запроса следующего содержания:

 

CREATE TABLE [dbo].[Tree] (

[id] [int] IDENTITY (1, 1) NOT NULL,

[parent_id] [int] NOT NULL,

[title] [varchar] (50) COLLATE Cyrillic_General_CI_AS NOT NULL,

[weight] [int] NOT NULL

) ON [PRIMARY].

 

Здесь столбец id хранит идентификаторы узлов дерева, а столбец parent_id — идентификаторы родительских узлов. Таким образом, вместе с каждым узлом хранится идентификатор его родительского узла.

Поля title и weight предназначены, соответственно, для хранения заголовка статьи и веса сортировки, назначенного этой статье. Вес сортировки необходим для визуализации заголовков статей в виде дерева. Чем выше вес сортировки, тем ниже располагается данная статья в дереве заголовков.

Можно было бы хранить тексты документов в самой таблице Tree, однако это привело бы к неэффективному расходованию памяти.

В самом деле, при отображении дерева мне фактически нужно загрузить в память все содержимое таблицы Tree. Однако в каждый момент времени пользователь просматривает или редактирует только одну статью, поэтому нет никакой необходимости загружать эти данные в память вместе со структурой дерева.

Для хранения текстов статей я создал отдельную таблицу Documents, содержащую столбцы id, document и tree_id. Первый из этих столбцов является ключевым. Ниже представлен sql-запрос, с помощью которого я создал таблицу Documents:

 

CREATE TABLE [dbo].[Documents] (

[id] [int] IDENTITY (1, 1) NOT NULL,

[document] [varchar] (5000) COLLATE Cyrillic_General_CI_AS NOT NULL,

[tree_id] [int] NOT NULL

) ON [PRIMARY]

 

В столбце id таблицы Documents хранятся уникальные идентификаторы статей, которые напрямую не используются в моём приложении.

Столбец tree_id хранит идентификатор узла дерева, соответствующего данной статье. Этот столбец является внешним ключом для таблицы Tree.

И, наконец, столбец document хранит текст самой статьи.

 

Хранимые процедуры

 

Часть работы с базой данных моё приложение будет выполнять при помощи команд SQL, оформленных в виде объектов класса SqlCommand. Однако на примере этого приложения я покажу как можно работать с хранимыми процедурами сервера Microsoft SQL Server.

Хранимая процедура sp_InsertDocument предназначена для добавления нового документа в таблицу Documents:

 

CREATE PROCEDURE [dbo].[sp_InsertDocument]

@tree_id AS INT,

@document AS VARCHAR(2000)

AS

INSERT INTO dbo.Documents(tree_id, document) VALUES (@tree_id, @document);

RETURN @@identity

 

Этой процедуре необходимо передать два параметра @tree_id и @document. Первый из этих параметров предназначен для передачи идентификатора узла, в который добавляется статья, а второй — для передачи текста этой статьи. Процедура возвращает идентификатор добавленной строки @@identity.

Хранимая процедура sp_ InsertNode вставляет новую строку в таблицу Tree, возвращая идентификатор новой строки:

 

CREATE PROCEDURE [dbo].[sp_InsertNode]

@parent_id AS INT,

@title AS VARCHAR(50),

@weight AS INT

AS

INSERT INTO dbo.Tree(parent_id, title, weight) VALUES (@parent_id, @title, @weight);

RETURN @@identity

 

Этой процедуре нужно передать через входные параметры идентификатор родительского узла @parent_id (равный 0 для корневого узла), заголовок статьи @title и вес сортировки @weight.

При помощи хранимой процедуры sp_UpdateDocument моё приложение обновляет тексты статей, хранящиеся в таблице Documents:.

 

ALTER PROCEDURE [dbo].[sp_UpdateDocument]

@tree_id as int,

@document AS VARCHAR(2000)

AS

UPDATE dbo.Documents SET document = @document WHERE (tree_id = @tree_id)

 

В качестве параметра этой хранимой процедуре необходимо передать идентификатор узла @tree_id обновляемой статьи, а также текст статьи @document.

 


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: