Текст книги "Программирование мобильных устройств на платформе .NET Compact Framework"
Автор книги: Иво Салмре
Жанр:
Программирование
сообщить о нарушении
Текущая страница: 47 (всего у книги 69 страниц)
Специфика .NET Compact Framework: ADO.NET
ADO.NET – мощная многоуровневая программная модель, предназначенная для работы с реляционными данными любого вида. ADO.NET доступна на настольных компьютерах и серверах как часть .NET Framework, а на устройствах – как часть .NET Compact Framework. Поддержка ADO.NET в .NET Compact Framework основана на подмножестве программной модели, предназначенной для настольных компьютеров и серверов.
Ключевым новшеством в модели данных ADO.NET для серверов, настольных компьютеров и устройств является полное отделение объекта ADO.NET DataSet от источника данных. Как только данные попали в ADO.NET DataSet, их можно сериализовать в виде XML-данных и сохранить в локальном файле или передать по сети на сервер, настольный компьютер или мобильное устройство.
Между объектом ADO.NET DataSet и базами данных, предоставившими данные, не требуется поддерживать постоянное соединение; это обстоятельство является замечательным с точки зрения масштабируемости серверов, поскольку необходимость в поддержании постоянного соединения отрицательно воздействует на этот их аспект.
Элементарные сведения об объектах ADO.NET DataSetДля работы с базами данных использование в приложении объекта ADO.NET не является обязательным
Объекты DataSet – замечательная абстракция, но они не всегда являются наилучшим способом организации доступа к данным. Если требуется только считывать данные, то имеет смысл работать непосредственно с данными, предоставляемыми объектом ADO.NET DataReader, сохраняя их в наиболее эффективном для задачи, которую вы пытаетесь решить, формате. Более подробно по этому поводу говорится далее в этой главе.
ADO.NET предлагает множество мощных концепций, которые поначалу кажутся сложными и обескураживают пользователей, привыкших работать с другими моделями доступа к данным. На самом же деле использовать ADO.NET довольно просто, но это требует от разработчика вдумчивого отношения к этой модели и означает отказ от понятия курсора данных как центрального механизма для работы с данными.
Чтобы вы смогли лучше во всем разобраться, целесообразно сравнить ADO.NET с ее предшественницей – технологией ADO. Как говорит само название, объект ADO.NET DataSet теснее связан с математической идеей "набора данных" (data set), чем с традиционной идеей ADO о "наборе записей" (record set), который представляет строки записей в таблице и предоставляет курсор, позволяющий переходить от одной записи к другой. Объекты ADO.NET DataSet "не имеют курсора" в том смысле, что в этом случае понятие текущей записи и курсора, осуществляющего переключение контекста при переходе от записи к записи, отсутствует. В ADO.NET DataSet все записи просто существуют в виде набора и допускают произвольные переходы между записями без использования курсора, отслеживающего текущую запись. Кроме того, объекты DataSet не являются специфичными по отношению к таблицам; объект ADO.NET DataSet может содержать любое количество таблиц данных, равно как и любое количество информации об отношениях между таблицами. Прежние объекты ADO RecordSet позволяют проходить по одной таблице, содержащую информацию, тогда как объекты ADO.NET DataSet позволяют исследовать одну или несколько таблиц данных.
Создание мостика между подходом, основанным на наборах данных, и моделью, в которой для работы с данными используются строки, обеспечивается объектами ADO.NET DataView и DataTable. Один объект DataSet может содержать любое количество объектов DataTable. Таблица данных (data table) фактически является массивом объектов, аналогичным таблице в базе данных. Объекты DataView – это объекты, предоставляющие методы фильтрации и сортировки поверх объектов DataTable, что позволяет добираться среди содержимого объекта DataSet до данных, которые представляют непосредственный интерес для вашего приложения. Объекты DataView могут также предоставлять отсортированное представление данных (data view), в котором данные упорядочиваются наиболее удобным для использования в приложении и отображения способом. С одной таблицей DataTable может быть связано произвольное количество объектов DataView, для каждого из которых определены свои критерии сортировки и фильтрации, позволяющие создавать пользовательские представления данных.
На настольных компьютерах и серверах .NET Framework поддерживает как "типизированные", так и "нетипизированные" объекты DataSet. В .NET Compact Framework специально поддерживаются только "нетипизированные" объекты DataSet. Может показаться, что тем самым создаются определенные ограничения, однако в действительности это не так, поскольку типизированные объекты DataSet являются просто классами, построенными поверх нетипизированных объектов DataSet, которые жестко связывают имена типизированных полей с лежащими в их основе элементами нетипизированных объектов DataSet. Поскольку типизированный объект DataSet строится поверх нетипизированного класса DataSet, то он, по сути, представляет собой удобную в использовании, но несколько медленнее работающую абстракцию. Приложения, в которых нетипизированные объекты DataSet используются корректным образом, путем поиска и кэширования объектов DataColumn используемых ими столбцов (columns) (в отличие от поиска полей по именам при каждом их использовании), демонстрируют такую же или даже еще лучшую производительность по сравнению с теми, в которых используются типизированные объекты DataSet.
Очень короткий пример использования объектов DataSet, DataTables и XML
Чтобы продемонстрировать основы работы с объектами ADO.NET DataSet, полезно обратиться к примеру. В документации .NET Framework содержится исчерпывающее описание ADO.NET и объектов DataSet. В примере будут показаны лишь самые элементарные операции создания и использования объектов DataSet с целью установления контекста для обсуждения использования ADO.NET на мобильных устройствах.
Приведенный в листинге 14.1 код позволяет создать приложение, представленное на рис. 14.1. Для создания приложения потребуется выполнить следующие действия:
1. Запустите Visual Studio .NET (2003 или более позднюю версию) и выберите в качестве типа приложения C# Smart Device Application.
2. Выберите в качестве целевой платформы Pocket PC. (Для вас будет автоматически создан проект, и на экране появится окно конструктора форм Pocket PC.)
3. Добавьте в форму элемент управления Button. (Ему будет автоматически присвоено имя button1.)
4. Добавьте в форму элемент управления TextBox. (Ему будет автоматически присвоено имя textBox1.)
5. Установите для свойства MultiLine элемента управления TextBox значение true и измените размеры текстового окна таким образом, чтобы оно заняло почти всю форму.
6. Установите для свойства ScrollBar элемента управления TextBox значение vertical.
7. Дважды щелкните на элементе управления Button в окне конструктора форм и введите код функции button1_Click(), приведенный в листинге.
8. Введите весь оставшийся код, приведенный в листинге 14.1.
9. Вернитесь в окно конструктора форм.
10. Установите для свойства MinimizeBox формы значение false. Благодаря этому во время выполнения в верхней правой части формы появится кнопка OK, с помощью которой вы легко сможете закрыть форму и выйти из приложения. Эта возможность оказывается очень полезной при многократном тестировании приложения.
11. Запустите приложение и щелкните на кнопке Button; полученные вами результаты должны воспроизводить те, которые представлены на рис. 14.1.

Рис. 14.1. Простой пример, демонстрирующий создание объекта ADO.NET DataSet
Листинг 14.1. Простой пример создания и использования объекта ADO.NET DataSet
//Объект DataSet, который мы собираемся загрузить
System.Data.DataSet m_myDataSet;
//Константы, которые будут использоваться
const string FILE_EMPTY_DATASET = "EmptyDataSet.xml";
const string FILE_1TABLE_DATASET = "1TableDataSet.xml";
const string dividerLine = "–rn";
const string nextLine = "rn";
//–
//Загрузить содержимое файла и присоединить его к тексту,
//содержащемуся в элементе управления textBox1
//–
private void addFileContentsToTextBox(string fileName) {
//Открыть файл и считать его содержимое
System.IO.StreamReader myStreamReader;
myStreamReader = System.IO.File.OpenText(fileName);
string fileText = myStreamReader.ReadToEnd();
//Закрыть файл
myStreamReader.Close();
//Присоединить содержимое к тексту, находящемуся в текстовом окне
textBox1.Text = textBox1.Text +
dividerLine + "FILE: '" + fileName + "'" + nextLine +
dividerLine + fileText + nextLine;
}
//–
//1. Создает набор данных,
// сохраняет набор данных в виде XML,
// отображает результаты в текстовом окне
//2. Добавляет таблицу данных в набор данных,
// добавляет два типизированных столбца в таблицу данных,
// добавляет две строки в таблицу данных,
// сохраняет набор данных в виде XML,
// отображает результаты в текстовом окне
//–
private void button1_Click(object sender, System.EventArgs e) {
//Очистить текстовое окно от содержимого
textBox1.Text = "";
//===========================================
//1. Создать новый набор данных
//===========================================
m_myDataSet = new System.Data.DataSet("HelloWorld-DataSet");
//Записать содержимое ADO.NET DataSet в виде XML и отобразить
//файл в текстовом окне
m_myDataSet.WriteXml(FILE_EMPTY_DATASET);
addFileContentsToTextBox(FILE_EMPTY_DATASET);
//==================================================
//2. Добавить таблицу данных в набор данных ADO.NET,
// а также 2 строки данных в таблицу данных
//==================================================
System.Data.DataTable myTestTable;
myTestTable = m_myDataSet.Tables.Add("TestTable");
//–
//Добавить 2 столбца в таблицу
//–
//Добавить столбец данных в таблицу DataTable набора DataSet
myTestTable.Columns.Add("TestColumn0", typeof(System.DateTime));
//Добавить строковый столбец в таблицу DataTable набора DataSet
myTestTable.Columns.Add("TestColumn1", typeof(string));
//–
//Добавить строки данных в таблицу
//–
//Добавить строку данных в таблицу данных
object[] rowOfData;
rowOfData = new object[2];
//Столбец 0 – это тип даты
rowOfData[0] = System.DateTime.Today;
//Столбец 1 – это строковый тип
rowOfData[1] = "а string of data today";
myTestTable.Rows.Add(rowOfData);
//Добавить вторую строку данных в таблицу данных
object[] rowOfData2;
rowOfData2 = new object[2];
//Столбец 0 – это тип даты
rowOfData2[0] = System.DateTime.Today.AddDays(1);
//Столбец 1 – это строковый тип
rowOfData2[1] = "tomorrow's string";
myTestTable.Rows.Add(rowOfData2);
//Записать содержимое набора ADO.NET DataSet в виде XML и отобразить
//файл в текстовом окне
m_myDataSet.WriteXml(FILE_1TABLE_DATASET);
addFileContentsToTextBox(FILE_1TABLE_DATASET);
} //Конец функции
Отслеживание изменения данных
Объекты ADO.NET DataSet автоматически отслеживают изменения, вносимые в содержащиеся в них данные, включая создание, удаление и изменение строк данных в таблицах данных. Затем эти изменения могут быть приняты или отвергнуты, а принятые изменения переданы в базу данных в соответствии с необходимостью. Если источник данных рассредоточен по нескольким базам данных, то возможно даже обновление данных с использованием распределенных транзакций.
Важно понимать, что объектам ADO.NET DataSet ничего не известно о базах данных, в которых данные хранятся постоянно; для восполнения этого пробела используются классы DataAdapter. Класс ADO.NET DataAdapter предназначен для перемещения данных между объектами ADO.NET DataSet и долговременными хранилищами. Все классы ADO.NET DataAdapter состоят из пользовательского кода; любая логика, необходимая для подключения к источнику данных, с которым ведется работа, получения этих данных и их обновления, пишется разработчиком. По сути дела, объекты ADO.NET DataSet представляют собой небольшие базы данных в памяти, и классы DataAdapter пишутся для того, чтобы обеспечить синхронизацию данных DataSet с базой данных; находится ли эта база данных на устройстве или на сервере, известно лишь коду адаптера данных (data adapter).
Объекты DataAdapter могут существовать либо на стороне клиента, либо на стороне сервера. Если адаптер данных находится на сервере, то для предоставления ему данных объекта ADO.NET DataSet их копия должна быть передана с клиента на сервер. Обычно передача набора данных DataSet с клиента на сервер осуществляется путем сериализации объекта DataSet в XML, передачи его на сервер и последующей реконструкции DataSet из XML. Для всего этого в ADO.NET предусмотрена встроенная поддержка. Данная модель хорошо приспособлена для работы с Web-службами. Во многих случаях желательно избавить клиента от необходимости знать что-либо о конечных базах данных, к которым осуществляется доступ; это позволяет упростить архитектуру приложения за счет централизации доступа к базе данных на сервере. В подобных случаях данные объекта ADO.NET DataSet обычно передаются с клиентского устройства Web-службе, выполняющейся на сервере. Web-служба повторно загружает XML-данные в объект ADO.NET DataSet, а затем передает их в адаптер данных ADO NET, который и выполняет все необходимые обновления на сервере. Следует отметить, что объекты ADO.NET DataSet обладают такими встроенными механизмами, которые позволяют передавать на сервер лишь те данные DataSet, которые претерпели изменения (так называемые "диффграммы" ("diffgram"), или диаграммы отличий), это избавляет от необходимости перемещения полностью всех данных, содержащихся в DataSet, если изменились только несколько строк.
Две модели использования ADO.NETADO.NET предлагает многоуровневый подход для работы с данными, что дает возможность выбрать тот уровень программной абстракции, который в наилучшей степени соответствует потребностям вашего мобильного приложения и требованиям производительности.
Высокоуровневый подход, основанный на использовании объектов ADO.NET DataSet
На самом высоком уровне абстракции доступа к данным платформа .NET Compact Framework предлагает наряду с объектами ADO.NET DataSet также объекты DataTable и DataView. Схема различных логических связей для приложений такого рода представлены на рис. 14.2. Как обсуждалось выше, центральное место в этой модели занимают объекты ADO NET DataSet.

Рис. 14.2. Подход к организации работы с данными, основанный на использовании объектов ADO.NET DataSet
Низкоуровневый подход, основанный на использовании объектов подключения к данным ADO.NET
Хотя объекты ADO.NET DataSet и предлагают необычайно широкие возможности для работы с данными, создание дополнительных объектов для абстрагирования и управления данными приложения и отношениями между ними приводит к увеличению накладных расходов. Иногда эти накладные расходы оказываются недопустимо высокими или нежелательными; в подобных случаях следует подумать об использовании альтернативного низкоуровневого варианта.
Альтернативный подход, в котором используются низкоуровневые абстракции ADO.NET, проиллюстрирован на рис. 14.3. В основе этого подхода лежит создание пользовательской модели управления данными поверх объектов подключения к данным (data connection objects), предоставляемых поставщиками данных (data providers) ADO.NET. Так, для обеспечения доступа к собственной базе данных SQL Server предлагает класс System.Data.SqlClient.SqlConnection, тогда как SQL СЕ для тех же целей предоставляет класс System.Data.SqlServerCe.SqlCeConnection. Обычно эти классы используются совместно с классами DataAdapter для обмена данными с объектами DataSet, но могут использоваться и сами по себе для получения и передачи данных с использованием ваших собственных форматов данных. Эта модель может обеспечить значительную экономию памяти, если мобильное приложение не нуждается в тех широких возможностях в отношении доступа к данным, которые предлагает универсальная модель на основе объектов ADO.NET DataSet. Схема различных взаимосвязей, соответствующая данному случаю, представлена на рис. 14.3.
В случае выбора низкоуровневого подхода ваше приложение берет на себя непосредственную ответственность за управление данными, загружаемыми в память, отслеживание любых изменений, вносимых в данные, и передачу этих изменений обратно в долговременное хранилище в соответствии с необходимостью. Снижение накладных расходов при работе на более низком уровне абстракции достигается за счет повышения ответственности разработчика за проектирование и поддержание эффективной модели данных.

Рис. 14.3. Альтернатива использованию объектов ADO.NET DataSet
Модель программирования, основанная на использовании объектов ADO.NET DataSet, предоставляет замечательные возможности для работы с реляционными данными, однако ее применение уместно не в любом контексте. Важно понимать, когда следует использовать ADO.NET для удовлетворения потребностей приложения в доступе к данным, а когда – не следует.
В каких случаях следует использовать объекты ADO.NET DataSet
Объекты ADO.NET DataSet следует использовать в тех случаях, когда приложению требуются широкие возможности манипулирования данными в памяти или когда возникает необходимость в использовании сложного реляционного способа прослеживания данных. Поскольку, по существу, ADO.NET поддерживает для вас в памяти небольшую реляционную базу данных, которая отслеживает вносимые изменения, то использование этого протокола предоставляет широкие возможности для автоматического управления набором в высшей степени динамичных данных, а также навигации по связям между отдельными порциями данных. Объекты ADO.NET DataSet оказываются удобными в тех случаях, когда 1) объем данных, с которыми вы должны работать, не слишком велик по сравнению с емкостью памяти мобильного устройства, и 2) данные имеют динамическую природу, что диктует необходимость отслеживания и распространения изменений.
Объекты ADO.NET DataSet обеспечивают обмен данными с долговременным хранилищем. Такой обмен осуществляется одним из трех способов: 1) использование классов DataAdapter, осуществляющих соединение с базами данных посредством объектов подключения к данным, 2) сериализация объектов DataSet в файлы и потоки XML и наоборот, и 3) сериализация посредством пользовательского кода, который считывает данные из объектов DataSet или помещает данные в указанные объекты. Краткие описания каждого из упомянутых способов передачи данных приводятся ниже.
Использование классов DataAdapter для организации взаимодействия с базами данных
Тип ADO.NET System.Data.Common.DataAdapter – это абстрактный класс, то есть он предоставляет шаблон для порождения других классов DataAdapter, специфических по отношению к базе данных, которые, собственно говоря, и используются. Вместе с .NET Compact Framework поставляются два адаптера данных:
1. SqlDataAdapter. Класс System.Data.SqlClient.SqlDataAdapter используется при работе с базами данных SQL Server, выполняющимися на серверах.
2. SqlCeDataAdapter. Класс System.Data.SqlServerCe.SqlCeDataAdapter используется при работе с базами данных SQL СЕ, выполняющимися на мобильных устройствах.
Для подключения к другим источникам данных могут использоваться адаптеры данных, предлагаемые сторонними производителями. Кроме того, вы можете написать собственный класс DataAdapter, если имеется пользовательский источник данных, к которому вы хотите подключиться.
Независимо от выбранного вами типа адаптера данных объекты DataAdapter работают посредством присоединенных к ним объектов Command. В отличие от класса DataAdapter у класса Command нет корневого класса, от которого могли бы быть произведены другие классы Command, специфические по отношению к базам данных; понятие класса Command существует лишь как понятие, которое используется при работе с различными адаптерами данных. Для объектов SqlDataAdapter существуют связанные с ними объекты SqlCommand, для объектов SQL СЕ SqlCeDataAdapter – объекты SqlCeCommand, и так далее. В свою очередь, с объектами Command связываются объекты Connection, которые отображают команды (commands) на конкретный экземпляр той или иной базы данных; например, для выполнения команд при работе через конкретное соединение с базой данных SQL Server объект SqlCommand будет использовать объект SqlConnection. Указанные объекты Command исполняют запросы и другие команды баз данных, которые должны выполняться для извлечения данных из баз данных или помещения их в базы данных, используемые вашим приложением. Объектам Command известно, как осуществлять те или иные действия при работе с той или иной базой данных, когда они выполняют SQL-команды для выборки, обновления, вставки или удаления данных. Так, для выполнения этих команд у класса SQLDataAdapter имеются следующие четыре свойства: SelectCommand, UpdateCommand, InsertCommand и DeleteCommand. Каждое из этих свойств имеет тип SqlCommand. Аналогичным образом, у объекта SqlCeDataAdapter также имеются четыре свойства с теми же именами, но типом этих свойств является SQLCeCommand.
Краткое подведение итогов. Адаптеры данных играют роль посредников при осуществлении связи между объектами ADO.NET DataSet и базами данных. Как правило, для выполнения этих функций адаптеры данных используют объекты Command. Объекты Command являются специфическими по отношению к каждому типу баз данных. В свою очередь, объекты Command обычно ассоциируются с объектами Connection, владеющими соединениями с конкретным сервером. В типичных случаях объект Command является владельцем таких SQL-операторов, как Select * from Customers, а объекты Connection – владельцами логического соединения с базой данных, через которое им передаются эти команды.
При создании .NET-приложений для настольных компьютеров и серверов Visual Studio .NET предлагает инструментальные средства времени проектирования, которые облегчают настройку конфигураций адаптеров данных и ассоциированных с ними классов Command; это значительно упрощает процесс доступа к базам данных. В отличие от этого, для создания и использования адаптера данных в .NET Compact Framework вы должны сами написать код, обеспечивающий конфигурирование объектов DataAdapter и Command для работы с используемыми вами источниками данных. Возможно, в будущем автоматизированные средства будут поддерживать также .NET Compact Framework и объекты DataAdapter и DataCommand для работы с популярными базами данных, но пока что вы можете полагаться только на самих себя. Поскольку предусмотренные для настольных компьютеров и серверов инструментальные средства для работы с базами данных автоматически генерируют исходный код для приложений, часто имеет смысл воспользоваться сгенерированным ими кодом и адаптировать его для выполнения на мобильных устройствах; хотя этот код и будет существенно отличаться от того, что вам нужно, он послужит вам неплохой отправной точкой.
Использование файлов и потоков XML для сохранения и передачи данных
Сохранение содержимого объектов ADO.NET DataSet в виде XML-файлов можно считать вариантом "базы данных для бедных". Данные приложения сохраняются в текстовом файле с использованием формата, который позволяет осуществить последующую повторную загрузку данных в память в виде объекта ADO.NET DataSet. Это аналогично получению объекта DataSet, возвращаемого через запрос Web-службы. В противоположность сохранению данных в базе данных использование текстового XML-файла для хранения данных лишает ваше приложение богатых возможностей транзакций и гарантий целостности данных, предлагаемых современными базами данных. Несмотря на ограниченность этой модели в отношении хранения больших объемов данных и возможности обновления данных посредством механизма транзакций, она может хорошо послужить при хранении данных небольшого объема (например, XML-файлы размером 20 Кбайт) или при перемещении данных на сервер посредством XML-потоков. Сохранение объектов DataSet в виде постоянно существующих XML-файлов можно рассматривать как простой способ упаковки небольших или средних объемов информации о состояния приложения для ее последующего повторного использования.
При записи содержимого объекта DataSet в файл или поток XML важно внимательно изучить опции, предлагаемые перечислением System.Data.XmlWriteMode. Исходя из соображений производительности, при сохранении объектов DataSet в виде постоянно существующих XML-файлов рекомендуется одновременно сохранять XML-схему (то есть использовать System.Data.XmlWriteMode.WriteSchema). Запись схемы данных вместе с самими данными обеспечивает существенное ускорение повторной загрузки XML-данных в объект DataSet; в противном случае схема должна будет динамически определяться во время повторной загрузки данных, а это потребует выполнения дополнительной работы. В листинге 14.2 представлен простой пример сохранения объекта DataSet в XML-файле. В этом примере предоставляется возможность задавать параметр WriteSchema.
Чтобы выполнить пример, дополните код, приведенный в листинге 14.1, кодом из листинга 14.2 и добавьте элемент управления Button, который вызывает функцию writeDataSetToFile.
Листинг 14.2. Использование параметра XMLWriteMode при сохранении объекта ADO.NET DataSet
//–
//Необходимость в этой функции возникает по той причине, что .NET Compact
//Framework не поддерживает перегрузку:
//
//"public void WriteXml(string, XmlWriteMode);"
//
//в качестве функции-члена "public" (только "private")
//–
void writeDataSetToFile(System.Data.DataSet ds, string filename, System.Data.XmlWriteMode xmlWriteMode) {
//Создать объект XmlWriter для записи наших XML-данных
System.Xml.XmlWriter xmlWriter;
xmlWriter = new System.Xml.XmlTextWriter(filename, System.Text.Encoding.Default);
//ПРИМЕЧАНИЕ: Эта перегруженная версия не является общедоступной (public)!
//ds.WriteXml(filename, xmlWriteMode);
//Вместо этого используем следующую функцию:
ds.WriteXml(xmlWriter, xmlWriteMode);
xmlWriter.Close(); //Важно закрыть файл!
}
Сериализация объектов ADO.NET DataSet с помощью пользовательского кода
Как ранее уже обсуждалось, объекты ADO.NET DataSet обладают встроенной поддержкой сохранения содержимого в виде XML-файлов. В то же время, этот XML-формат не является произвольным и должен соответствовать определенной схеме XML, предназначенной специально для использования с объектами ADO.NET DataSet. Если вашему приложению необходимо выполнять запись или считывание информации с использованием другой схемы XML или любого другого формата, то для этого вы должны сами написать код соответствующей пользовательской логики. Модель, основанная на использовании объектов DataSet, обладает достаточной гибкостью для того, чтобы обеспечить поддержку сохранения данных в любом желаемом виде. Поскольку объекты ADO.NET DataSet поддерживают в памяти простую базу данных, не зависящую от формата хранения, вы можете сохранить этот объект в любом формате (например, в пользовательском формате XML, двоичном, простом текстовом), который отвечает вашим потребностям. Следует лишь отметить, что прежде чем взваливать на себя дополнительную работу по проектированию, необходимо убедиться в том, что для этого имеются серьезные основания.
Если вы пишете пользовательский код десериализации для заполнения данными объекта DataSet, то код вашего приложения должен программным путем построить таблицы, столбцы и определения отношений, а затем заполнить таблицы импортируемыми данными. Аналогичным образом, при пользовательском сохранении объекта DataSet логика вашего приложения должна обеспечить итерирование по всем таблицам и сохранение данных с использованием любого желаемого механизма. Для чтения и записи данных с использованием нескольких различных источников можно привлечь гибридную модель; например, объект DataSet может автоматически заполняться данными при помощи объекта SQLDataAdapter, подключенного к базе данных SQL, а впоследствии эти данные могут быть сериализованы с применением пользовательского формата, локального для устройства. Объектам ADO.NET DataSet безразлично, каким именно образом данные были в них помещены и откуда они поступили.
Работа с нетипизированными объектами DataSet
В .NET Framework для настольных компьютеров и серверов предлагается концепция "типизированных объектов DataSet". Типизированный объект DataSet – это строго типизированный набор интерфейсных классов, реализованных посредством механизма наследования поверх объектов DataSet, DataTable и других объектов данных ADO.NET. Такие унаследованные классы обеспечивают доступ к базовым таблицам и строкам объектов DataSet с использованием строго типизированных членов класса, имена которых совпадают с именами обрабатываемых таблиц и столбцов. Например, вместо того чтобы осуществлять поиск столбцов по именам в соответствии с поздним связыванием (например, myDataRow["CustomerFirstName"]) или требовать использования индексов столбцов (myDataRow[2]), разработчик может использовать раннее связывание свойства (myDataRow.CustomerFirstName). Именно такое связывание на стадии проектирования и есть то, что делает объект DataSet "типизированным". Исходный код для типизированных классов DataSet автоматически генерируется средой времени проектирования Visual Studio .NET.
НА ЗАМЕТКУ
Важно отметить, что строго типизированные объекты DataSet ничуть не эффективнее нетипизированных объектов DataSet. Часто ошибочно полагают иное, поскольку раннее связывание интуитивно представляется более эффективным. Однако раннее связывание типизированных объектов DataSet просто перекладывается на основные нетипизированные объекты DataSet. Типизированные классы DataSet не работают быстрее, их просто легче использовать. Строго типизированные интерфейсные классы позволяют использовать во время проектирования такие возможности, как автоматическое завершение ввода операторов, что облегчает разработку программных кодов на основе объектов DataSet. Они также обеспечивают возможность выявления некоторых видов синтаксических ошибок на стадии проектирования, а не на стадии выполнения. Ничего сверх этого в плане производительности они не дают.
.NET Compact Framework не поддерживает компиляцию кода типизированных объектов DataSet, автоматически сгенерированного для настольных компьютеров, Это означает, что наиболее распространенным методом работы с объектами ADO.NET DataSet с использованием .NET Compact Framework является работа непосредственно с нетипизированным классом DataSet и подчиненными ему классами DataTable, DataColumn и DataRow. Кроме некоторого усложнения вашего кода и необходимости внимательно следить за тем, чтобы не допустить опечаток в именах столбцов и полей (распространенная ошибка), использование нетипизированных объектов DataSets не обладает никакими другими недостатками. Наиболее высокая производительность достигается тогда, когда вы работаете с нетипизированными классами непосредственно, а не через какие-либо интерфейсные уровни.







