« Поставить закладку » « Сделать стартовой »

« Форумы » « Блоги » « Статьи » « Новости » « Файлы » « Realcoding IRC » « Site map » « Поиск »


Главная Главная
Анонсы Анонсы
Форумы Форумы
Каталог Каталог
Поиск Поиск
Опросы Опросы
Книжный магазин Книжный магазин
Реклама на сайте
Публикации Публикации
Партнеры Партнеры
Карта Карта сайта
Рассылки Рассылки
RSS экспорт
Настройки Настройки
О нас пишут О нас пишут
Контакты Контакты
Гостевая книга Гостевая книга


ПнВтСрЧтПтСбВс
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        
    Популярное
Кроссплатформенное решение imagettftext(): Invalid font filename на Windows

Описание функций C (Си) / C++ - fscanf

FAQ по работе с редактором

Функция AccessResource

Соединение всех компонентов надписи и их текстовая обработка

Использование управляющего элемента Menu (Меню)

Функции просмотра и ссылки

Обзор Visual Basic 9.0

Интерфейс IShellFolder

Работа с Jpeg-изображениями в Delphi




    Архив файлов



    Сообщества

    Документация

    Кто на сайте
Вы не зарегистрированы.
Имя:

Пароль:

Запомнить

Регистрация позволит Вам пользоваться дополнительными сервисами.
Сейчас на сайте:
Гостей: 159
Пользователей: 0

Статьи:: Базы данных :: ADO .NET :: Работа с автономными данными в ADO.NET



отправить ссылку другу версия для печати  Обсудить на форуме

Работа с автономными данными в ADO.NET



Кондратьев Денис
visualdesign.ru

   Технология ADO.NET, в отличие от своих предшественников ADO и OLE DB, была разработана специально для использования в web приложениях, где не бывает постоянных соединений с БД. Традиционная работа с данными в ADO.NET строится по такой схеме: создается соединение Connection, затем оно открывается методом Open, создается объект команда Command, инкапсулирующая SQL команду, она исполняется, а соединение затем закрывается. Такой подход обеспечивает поточный доступ к результатам запросов. Т.е. читая данные с помощью DataReader, вы не можете перепрыгнуть через несколько записей или вернуться к предыдущей. Поточный доступ имеет максимальную производительность.
   ADO.NET была разработана для доступа к данным без реального соединения с БД. При этом все данные размещаются в оперативной памяти. Работа с отсоединенными данными в ADO.NET осуществляется с помощью классов из пространства имен System.Data.

Основные классы для работы с отсоединенными данными

   Самый выжный класс при работе с отсоединенными данными – это DataSet. После того как получены результаты запроса с помощью объекта DataAdapter и сохранены в DataSet' e, соединение между БД и объектом DataSet перестает существовать. Изменения в DataSet не сказываются на БД и наоборот. Класс DataSet включает в себя набор таблиц DataTable и связей между таблицами DataRelation. Класс DataTable включает набор строк DataRow, набор столбцов таблицы DataColumn, и наборы отношений ChildRelations и ParentRelations между столбцами разных таблиц базы данных. Класс DataRow инкапсулирует информацию о строке в таблице и состоянии строки Deleted, Modified, New и Unchanged. Класс Constraint используется для сохранения целостности данных в таблицах.

   Преимущества работы с отсоединенными данными:
      1. не требуется постоянное соединение с БД, что нужно, например, для web приложений;
      2. облегчается создание многоуровневых приложений. Если приложение обращается к БД с помощью объектов уровня DAL, то бизнес объектам на уровне BLL можно передавать DataSet. Обновления в БД также могут передаваться с помощью DataSet;
      3. облегчается сортировка, поиск, фильтрация и навигация по данным;
      4. облегчается работа с реляционными данными;
      5. есть возможность кешировать изменения. Объект DataSet позволяет кешировать изменения и затем с помощью DataAdapter передавать все изменения в БД за 1 раз;
      6. тесная интеграция с XML. Содержимое DataSet можно загружать и сохранять в виде XML документов.

Использование объектов DataSet

   Ниже приводится пример использования объекта DataSet. Все примеры в статье используют БД Northwind БД MS SQL Server.

stringconn ="Provider=SQLSQL;Data Source=(local)\NetSDK;InitialCatalog=Northwind;Trusted_Connection=Yes;";
string query = "SELECT CustomerID, CompanyName, ContactName, Phone FROM Customers";
SqlDataAdapter da = new SqlDataAdapter(query, conn);
DataSet ds = new DataSet();
da.Fill(ds, "Customers");

   Вначале создаем строку соединения с БД и SQL запрос для получения данных. DataAdapter помещает результаты запроса в соответствующую таблицу DataTable, находящуюся в DataSet. С помощью перегруженного метода Fill можно помещать данные и напрямую в DataTable. Для одной таблицы можно несколько раз вызывать метод Fill, однако, если вызывать метод Fill для DataSet без явного указания имени таблицы, то эти данные будут помещаться в разные таблицы (например, "Table", "Table1", "Table2",). Для доступа к данным, находящимся в таблицу есть свойство Rows, возвращающее набор объектов DataRow

DataTable table = ds.Tables[0];
DataRow row = table.Rows[0];
Console.WriteLine("OrderID: " + row["OrderID"]);
Console.WriteLine("CustomerID: " + row["CustomerID"]);  

   У объекта DataRow есть свойство Item, возвращающее содержимое конкретного поля. Можно указать имя поля как в примере кода, или целое число, соответствующее порядковому номеру столбца. При поиске по индексу данные немного возвращаются быстрее, чем при поиске по названию столбца.  
Изменение содержимого DataTable
   Для добавления новой строки в таблицу существует метод NewRow(), который создает новый объект DataRow, но не добавляет запись в таблицу. Полем новой записи задаются значения по умолчанию или Null, если значение по умолчанию не задано.

DataRow row = ds.Tables["Customers"].NewRow();
row["CustomerID"] = "VASYA";
row["Company"] = "Компания";
row["ContactName"] = "Вася Пупкин";
row["Phone"] = "11-22-33";
ds.Tables["Customers"].Rows.Add(row);

   Есть еще один способ добавления записей в таблицу – метод LoadDataRow(). Первый параметр этого метода – это массив значений, элементы которого соответствуют столбцам таблицы. Второй – позволяет управлять значением свойство RowState новой записи. Если передать false, то значение этого свойства будет Added, как и при добавлении новой записи методом Add.

object[]aValues = {"VASYA", "Компания",  "Вася Пупкин", "11-22-33"};
ds.Tables["Customers"].LoadDataRow(aValues, false);

   Редактирование существующей записи можно следующим образом:

DataRow row = ds.Tables["Customers"][0];
row["ContactName"] = "Вася Пупкин";

или с помощью метода ItemArray:

object[] items = {"VASYA", "Компания", "Вася Пупкин", "11-22-33"};
DataRow row = ds.Tables["Customers"][0];
Row.ItemArray = items;

   Для удаления записи нужно вызывать метод DataRow.Delete(). При этом удаленная запись фактически не удаляется из DataTable, а помечается как удаленная – ее свойство RowState принимает значение Deleted. Если же до вызова метода Delete значение RowState было Added, тотолько в этом случае строка удаляется из таблицы.

Использование столбцов с автоинкрементном

   Для поддержки столбцов с автоматическим увеличением значения у DataColumn есть свойства AutoIncrement, AutoIncrementSeed и AutoIncrementStep . Для того, чтобы создать столбец DataColumn с автоинкрементом нужно установить свойство AutoIncrement в true. Значение счетчика будет начинаться с AutoIncrementSeed (если это не нарушает корректность данных в таблице) и увеличиваться на значение AutoIncrementStep. Для столбцов с автоинкрементном рекомендуется устанавливать свойство ReadOnly в true. Ниже приведен пример вставки в таблицу столбца с автоинкрементом

DataColumn column = table.Columns.Add("CustomerID", typeof(Int32));
column.AutoIncrement = true;
column.AutoIncrementSeed = 1;
column.AutoIncrementStep = 1;

   Если вы планируете сносить изменения в БД методом DataAdapter.Update(), то рекомендуется задать свойствам AutoIncrementSeed и AutoIncrementStep значения -1. Это гарантирует, что ADO.NET будет генерировать значения метки, которых нет в БД. При вызове метода Update в БД внесутся уже уникальные значения.

Работа с DataSet в среде Visual Studio .NET

   Создавать объекты DataSet можно как программно, так и с помощью среды Visual Studio. Для второго случая предназначена вкладка Data в панели инструментов. Для начала нужно перетащить на web или win-форму объект SqlDataAdapter.

Панель Data

   Затем в мастере создать новое подключение к БД, указав БД Northwind и способ доступа к БД как «Use SQL statements». После этого выберете таблицу Customers и отметьте все столбцы таблицы.

Мастер Data Adapter Configuration Wizard

   Повторите процесс для таблицы Order, используя уже готовое соединение. Затем щелкните правой кнопкой мыши по панели с созданными DataAdapter 'ами, выберете из контекстного меню команду Generate DataSet.

Генерация DataSet из контекстного меню

   Отметьте галочками оба DataAdapter и нажмите на ОК.

Создание DataSet

   Добавленный объект DataSet отобразился в панели компонентов. Мы добавили т.н. DataSet со строгим контролем типов (типизированный DataSet ), о котором будем говорить позже. Структуру данных можно посмотреть в созданном файле с расширением xsd.

Объект DataSet на панели

Работа с реляционными данными

   Работа с реляционными данными осуществляется с помощью объектов класса DataRelation, связующие колонки DataColumn двух таблиц DataTable. Создать такой объект можно следующим образом:

ds.Relationships.Add(new DataRelation("CustomersOrders", ds.Tables["Customers"].Columns["CustomerID"], ds.Tables["Orders"].Columns["CustomerID"]);

   Если нужно определить отношение, основанное на нескольких столбцах, нужно использовать конструктор, принимающий массив объектов DataColumn:

DataTable tblParent = ds.Tables["ParentTable"];
DataColumn[] colsParent = new DataColumn[] {tblParent.Columns["ParentColumn1"], tblParent.Columns["ParentColumn2"]};
DataTable tblChild = ds.Tables["ChildTable"];
DataColumn[] colsChild = new DataColumn[] {tblChild.Columns["ChildColumn1"], tblChild.Columns["ChildColumn2"]};
ds.Relationships.Add(new DataRelation("ParentChild", colsParent, colsChild));

Работа со связанными данными

   Основным применением объектов DataRelation является поиск связанных данных. Однако сам объект DataRelation не предоставляет такой функциональности, она реализуется методами класса DataRow: GetChildRow(), GetParentRow() и GetParentRows().
   Для поиска дочерних записей используется метод GetChildRow() соответсвующего объекта DataRow. Ему передается ему имя объекта DataRelation, определяющего отношение. Этот метод возвращает дочерние записи в виде массива объектов DataRow :

DataRow row = ds.Tables["Customers"].Rows[0];
foreach (DataRow rowOrder in row.GetChildRows("CustomersOrders"))
   Console.WriteLine(rowOrder["OrderID"] + rowOrder["OrderDate"] + "n");

   Найти родительскую запись с помощью DataRelation можно методом DataRow.GetParentRow ().

DataRow rowOrder = ds.Tables["Orders"].Rows[0];
Console.WriteLine("t" + rowOrder.GetParentRow("CustomersOrders")["ContactName"] + "n");

   В случае отношения «один ко многим» найти все родительские записи конкретного объекта DataRow можно с методом GetParentRows(), также принимающего название отношения и возвращающего массив родительских объектов.

Добавление объекта DataRelation в Visual Studio .NET

   Для добавления отношения DataRelation в DataSet со строгим контролем типов нужно перейти к структуре данных, щелкнув по файлу с расширением xsd, определяющего структуру DataSet. Щелкнув на родительский DataTable правой кнопкой нужно в контекстном меню выбрать Add / New Relation.

Структура DataSet в xsd файле

   В диалоговом окне Edit Relation задаются родительские и дочерние объекты.

Задание родительских и дочерних объектов

   При щелчке на ОК, в XML Sheme Designer появляется графическое представление DataRelation – линия, соединяющая 2 объекта.

Отображение отношения

Поиск записей

   При запросах к БД часто требуется найти запись по ее первичному ключу. Для поиска записей в DataTable существует метод DataRowCollection.Find ().

table.PrimaryKey = new DataColumn[] {tbl.Columns["CustomerID"]};
DataRow row = tbl.Rows.Find("VASYA");
if (row == null)
   Console.WriteLine("Запись не найдена");
else
   Console.WriteLine(row["CompanyName"]);

   Если первичный ключ состоит из нескольких колонок, то в метод Find() можно передать массив объектов.
   Для выполнения поиска по произвольному SQL запросу у DataTable есть метод Find(). Например, для получения имен всех покупателей, находящихся в Уфе, можно воспользоваться таким кодом

DataRow[] rows = table.Select("City = 'Уфа'");
foreach (DataRow row in rows)
   Console.WriteLine(row["CompanyName"] + "n");

   Если нужно, чтобы возвращаемые данные были отсортированы, можно воспользоваться перегруженной версией этого метода. Она имитирует раздел ORDER BY SQL -запроса.

DataRow[] rows = table.Select("City = 'Уфа'", "CompanyName ASC");

Работа с объектами DataSet со строгим контролем типов

   Ранее мы уже создавали объекты DataSet со строгим контролем типов. Рассмотрим, какие новые функции появились у типизированного DataSet.
Добавление записи
   Все классы, соответствующие таблицам DataTable в DataSet, позволяют добавлять новые записи двумя способами. Метод New[Имя_таблицы]Row() возвращает новую строку в таблице:

DataSetTest ds = new DataSetTest();
DataSetTest.CustomersDataTable tblCustomers = ds.Customers;
DataSetTest.CustomersRow rowCustomer = tblCustomers.NewCustomersRow();
rowCustomer.CustomerID = "VASYA";
rowCustomer.CompanyName = "Компания";
rowCustomer.ContactName = "Вася Пупкин";
rowCustomer.Phone = "11-22-33";
tblCustomers.AddCustomersRow(rowCustomer);

   Второй способ – это использовать метод Add[Имя_таблицы]Row(), принимающий массив объектов, соответсвующих полям записи:

DataSetTest ds = new DataSetTest();
DataSetTest.CustomersDataTable.AddCustomersRow("VASYA", "Компания", "Вася Пупкин", "11-22-33");

Поиск записи
   Поиск записи в таблице тоже претерпел изменения. Например, для поиска в таблице Order Details по составному ключу появился метод следующий метод

DataSetTest.Order_DetailRow = tblDetails.FindByOrderIDProductID(112233, 456);

   Также типизированные DataSet поддерживают русские буквы в названиях таблиц и полей таблиц.

ds.Статистика.AddСтатистикаRow(15.9, "компания", true );

Передача обновлений в БД

   Для передачи изменений в БД используется объекты DataAdapter. Для создания логики обновления БД можно использовать один из трех вариантов:
1. вручную сконфигурировать DataAdapter в период разработки;
2. воспользоваться объектом CommandBulder в период выполнения;
3. использовать в период разработки DataAdapter Configuration Wizard.

Ручное конфигурирование DataAdapter
   DataAdapter имеет 3 свойства для передачи изменений в БД: InsertCommand, UpdateCommand и DeleteCommand. Значения этих свойства должны быть заданы до вызова метода DataAdapter.Update() с учетом того, какие изменения были внесены в DataSet. Когда метод Update() добавляет, обновляет или удаляет строки в таблице, он вызывает соответствующую команду.
   Если в ходе ваших действий вы только добавляли строки в таблицу, то и задать вы должны только значение InsertCommand. Ниже приведен код для такой ситуации:

string conn  = "Provider = SQLSQL; Data Source = (local)\NetSDK; Initial Catalog= Northwind; Trusted_Connection=Yes;";
string query = "SELECT CustomerID, CompanyName, ContactName, Phone FROM Customers"; SqlDataAdapter da = new SqlDataAdapter(query, conn); DataSet table = new DataSet(); da.Fill(table, "Customers");

// добавляем новые строки в таблицу
...

// создаем команду для вставки новых записей
query  = "INSERT INTO Customers (CustomerID, CompanyName, ContactName, Phone) VALUES (?, ?, ?, ?)";
SqlCommand cmd = new SqlCommand(query, conn);
SqlParameterCollection pc = cmd.Parameters; pc.Add("CustomerID", SqlType.Integer, 0, "CustomerID");
pc.Add("CompanyName", SqlType.String, 0, "CompanyName");
pc.Add("ContactName", SqlType.String, 0, "ContactName");
pc.Add("Phone", SqlType.String, 0, "Phone");
da.InsertCommand = cmd;
da.Update(table);

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

OleDbCommand cmd = new OleDbCommand("spInsertCustomer", conn);
cmd.CommandType = CommandType.StoredProcedure;
OleDbParameterCollection pc = cmd.Parameters;
pc.Add("CustomerID", SqlType.Integer, 0, "CustomerID");
pc.Add("CompanyName", SqlType.String, 0, "CompanyName");
pc.Add("ContactName", SqlType.String, 0, "ContactName");
pc.Add("Phone", SqlType.String, 0, "Phone");

Использование CommandBuilder
   CommandBuilder генерирует SQL запросы обращаясь к БД для получения метаданных о таблицах. Для использования CommandBuilder необходимо выполнение следующих условий: 1. запрос возвращает данные только из одной таблицы;
2. в таблице определен первичный ключ;
3. первичный ключ есть в результатах запроса.
   Ниже приведен пример использования CommandBuilder.

string con ="Provider=SQLOLEDB;Data Source=(local)\NetSDK;InitialCatalog=Northwind;Trusted_Connection=Yes;";
string query = "SELECT OrderID, ProductID, Quantity, UnitPrice FROM [Order Details]";
OleDbDataAdapter da = new OleDbDataAdapter(strSQL, strConn);
OleDbCommandBuilder cb = new OleDbCommandBuilder(da);
da.InsertCommand = cb.GetInsertCommand();
da.Update(tbl);

Использование мастера Data Adapter Configuration Wizard
   Одно из предназначений мастера – создание логики обновления базы данных. На четвертом шаге мастера по команде Advanced Options выводится диалог, в котором можно указать создавать или нет команды для вставки, обновления и удаления записей в БД.

Задание свойств DataSet

   На третьем же шаге работы мастер можно указать способ передачи обновления в БД: с помощью SQL запросов, с помощью существующей хранимой процедуры или создание новой хранимой процедуры. Никаких дополнительный действий для создания логики обновления не нужно.

Задания способа доступа к БД




Рубрика: ADO .NET




Вышел MySQL 5.1.30, первый стабильный рели....

MySQL

После публикации 29 тестовых версий анонсирован первый стабильный релиз MySQL 5.1, пригодный для промышленной эксплуатации и обеспечивающий увеличение производительности для "тяжелых" SQL запросов, по сравнению с MySQL 5.0, примерно на 15-20%. Главные новшества появившиеся в MySQL 5.1:


Подробнее... | Рубрика: MySQL | Добавлено: 28.11.2008

Тестирование параллельных программ.

Тестирование

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


Подробнее... | Рубрика: Тестирование | Добавлено: 28.11.2008

Архитектура AMD64 (EM64T).

Архитектура AMD

Аннотация. В статье кратко рассматривается архитектура AMD64 компании AMD и ее реализация EM64T компании Intel. Описаны особенности архитектуры, ее возможности, достоинства и недостатки.


Подробнее... | Рубрика: Архитектура AMD | Добавлено: 27.11.2008

Остальные статьи:

Платформа 2009. Определяя будущее
Windows Vista Bridge Sample Library - упра...
Оптимизация 64-битных программ
Подгрузка через AJAX HTML-кода, содержащег...
Обзор нового релиза самой мощной Ajax библ...
Firebug 1.3 и 1.4 alpha — что нового и инт...
Релиз Microsoft Silverlight 2.0. Что новог...
XML документация в C#
Курсоры в MySQL 5
Microsoft опубликовала подробности о сесси...
Microsoft делится подробностями о том, что...
Тестируем новый javascript от нового брауз...
MySQL Query Cache
Использование провайдеров компиляции в As...
Чего мы ждем от C# 4.0
Delphi 2009 и C++Builder 2009
Джоэл Спольски и Джеф Этвуд запустили новы...
Поиск кода Google /* что нового? */
10 jQuery скриптов для улучшения интерфейс...
Генераторы отчетов FastReport 4 и QuickRep...


Цитата дня (все,добавить):

Портал фрилансеров

работа на дому


    Рубрикатор

Программирование

C/С++
Обучение
Windows API
XAML
Моделирование
Паттерны
Visual Basic 7 .NET
WxWidgets
Функции WinApi
Функции С++
Разработка под Mac OS
Eiffel
Visual Studio 2008
UI дизайн
Алгоритмы
Конкурсные статьи
Turbo Pascal
Visual Studio
CASE-средства
Visual Studio 2005
Без VCL
Delphi
Тех. документация
Тестирование
Software Testing
ООП
TCP/IP
Google Android
Windows Installer
.NET Framework
Драйвера
C# C Sharp
Справка
Проектирование
Информ. системы
Visual Basic
Assembler
Оптимизация кода
Gtk+
Компоненты
Реинжиниринг
Управление проектами
Extreeme programming
Lotus Notes
Алгебраическое проектирование


Интернет технологии

PHP
Perl
ASP
WAP
Cookies
SSI
CGI
Web Servers
VB Script
DNS
CSS
XML
Html
Java Script
Java2ME
Firewall
Flash
.htaccess
Apache
VRML
Протоколы
Поисковые системы
Технология JAVA
Учебник по PHP
Учебник по JavaScript
Учебник по XML
Java Q&A
AJAX
DHTML
XHTML
Dreamweaver
Web 2.0
Python
Вебмастеру
Cisco
Ruby on Rails
Silverlight

Базы данных

Access
InterBase
MySQL
Oracle
ADO .NET
Основы SQL
Учебник по Access 2002
MS
Microsoft FoxPro
Доступ к данным
XML в MS SQL Server 2000
ODBC и MyODBC
Обучение
Caché
DB2
PostgresSQL
Sybase
Теория
Хранилища данных
Безопасность
Реляционные данные
MySQL и mSQL

Остальное:

Разное
Обзоры книг
Безопасность
Графика и дизайн
Юмор
Linux
Фракталы
Microsoft Axapta
Многоядерность
Сети
Microsoft Office
Работа
MS-DOS
Криптография
Графика и игроделание
Новости SDK
Системы защиты
Учебник по AutoCad
CVS
Windows XP
Windows Server 2003
Windows Vista
Windows 7
Мероприятия