Затем вы переходите от таблицы Customers к таблице Orders, используя отношение CustomerOrder. Обратите внимание на то, что метод DataRow.GetChildRows позволяет получить доступ к строкам дочерней таблицы. После этого вы можете прочитать информацию из этой таблицы.
// Переход от таблицы заказчиков к таблице заказов.
DataRow[] drsOrder = null;
drsOrder = drCast.GetChildRows(carsDS.Relations["CustomerOrder"]);
// Получение номера заказа.
foreach(DataRow r in drsOrder) strInfo += "Номер заказа: " + r["OrderID"] + "\n";
Заключительным шагом является переход от таблицы Orders к родительской таблице (Inventory) с помощью метода GetParentRows. После этого вы сможете прочитать информацию из таблицы Inventory для столбцов Make
// Переход от таблицы заказов к таблице ассортимента.
DataRow[] drsInv = drsOrder[0].GetParentRows(carsDS.Relations["InventoryOrder"]);
foreach(DataRow r in drsInv) {
strInfo += "Марка: " + r["Make"] + "\n";
strInfo += "Цвет: " + r["Color"] + "\n";
strInfo += "Название: " + r["PetName"] + "\n";
}
На рис. 22.21 показан один из возможных вариантов вывода.
Рис. 22.21. Навигация по связанным данным
Этот пример убеждает в пользе типа DataSet. Поскольку DataSet отсоединяется от соответствующего источника данных, вы можете работать с копией данных, размещенной в памяти, переходя от одной таблицы к другой и выполняя все необходимые модификации, удаления или вставки. По завершении этой работы вы можете направить свои изменения в хранилище данных для их обработки.
Исходный код. Проект MultitabledDataSetApp размещен в подкаталоге, соответствующем главе 22.
Возможности мастеров данных
К этому моменту нашего рассмотрения вы открыли для себя множество путей взаимодействия с типами ADO.NET без использования мастеров. Но, хотя понимание основ работы с поставщиком данных оказывается (определенно) важным, важно и то, что от больших объемов вводимого вручную, в общем-то, шаблонного программного кода могут болеть руки. Поэтому в завершение мы рассмотрим несколько мастеров данных, которые могут вам при случае пригодиться.
Здесь не ставится цель комментировать все мастера данных для интерфейса пользователя, имеющиеся в Visual Studio 2005, но чтобы показать их основные возможности, мы рассмотрим некоторые дополнительные опции конфигурации элемента управления DataGridView. Создайте новое приложение Windows Forms с одной формой, содержащей элемент управления DataGridView с именем inventoryDataGridView. В окне проектирования формы активизируйте встроенный редактор этого элемента, и в раскрывающемся списке Choose Data Source (Выбрать источник данных) щелкните на ссылке Add Project Data Source (Добавить источник данных в проект), рис. 22.22.
Рис. 22.22. Добавление источника данных
В результате будет запущен мастер конфигураций источников данных. На первом шаге проста выберите пиктограмму Database и щелкните на кнопке Next. На втором шаге щелкните на кнопке New Connection (Новое соединение) и установите связь с базой данных Cars (используя вышеприведенные инструкции из раздела "Соединение с базой данных в Visual Studio 2005" этой главы). Третий шаг позволяет мастеру сохранить строку соединения во внешнем файле Арр.config в рамках должным образом сконфигурированного элемента ‹connectionStrings› (что, в общем-то, является довольно хорошим решением). На заключительном шаге вы получаете возможность выбрать объекты базы данных, которые должны использоваться генерируемым объектом DataSet, и для вашего примера это будет одна таблица Inventory (рис. 22.23).
По завершении работы мастера вы увидите, что элемент DataGridView в окне проектирования формы автоматически отображает имена столбцов. И если выполнить приложение в том виде, в каком оно находится сейчас, вы увидите все содержимое таблицы Inventory, отображенное в окне указанного элемента интерфейса. Если рассмотреть программный код для события Load вашей формы, вы обнаружите, что элемент управлений заполняется с помощью строки программного кода, выделенной здесь полужирным шрифтом.
public partial class MainForm: Form {
public MainForm {
InitializeComponent;
}
private void MainForm_Load(object sender, EventArgs e) {
// TODO: This line of code loads data into
// the 'carsDataSet.Inventory' table.