Введение в ADO.NET. Источник данных - XML-файл. Отображение данных связанной таблицы, страница 6

Да, так и есть. В пространстве имен System.Data определен класс Constraint и коллекция (Constraints) ссылок на объекты этого класса имеется в каждой таблице. Класс Constraint является абстрактным, поэтому на самом деле в коллекции хранятся ссылки на объекты производных классов: UniqueConstraint и ForeignKeyConstraint.

В момент создания первичного ключа (см. код table.PrimaryKey = new DataColumn[] { dc };) подсистема ADO.NET автоматически конструирует UniqueConstraint и вставляет ссылку на него в коллекцию Constraints любой из наших таблиц. Для того, чтобы убедиться в этом выполните следующий код в режиме отладки и просмотрите объект cs в окне Watch или Quick Watch (этот фрагмент временный — выбросьте его после).

Constraint cs = studs.Constraints[0];

cs = exams.Constraints[0];

Следующий фрагмент надо добавить в InitDataSet (до создания DataRelation). Здесь мы создаем объект класса ForeignKeyConstraint, настраиваем его и вставляем в коллекцию Constraints подчиненной таблицы.

ForeignKeyConstraint cs = new ForeignKeyConstraint("StudExam",

  studs.Columns["ID"], exams.Columns["StudID"]);

cs.DeleteRule = Rule.Cascade;

cs.UpdateRule = Rule.Cascade;

exams.Constraints.Add(cs);

ds.EnforceConstraints = true;

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

Вторая, подчиненная таблица

¨  Добавьте в форму еще один элемент типа DataGridView с идентификатором examsGrid, в котором мы будем отображать данные таблицы экзаменов.

¨  Разработайте код инициализации данных новой таблицы. Сгенерируйте для каждого студента случайное количество сданных экзаменов, случайные даты и оценки. Пользуйтесь методами класса Random.

¨  Привяжите examsGrid к данным таблицы Exams.

¨  Добавьте метод AddStyleExam для коррекции стилей колонок второго DataGridView.

Приведем решение последней задачи (коррекция стилей второго DataGridView).

  foreach (DataColumn dc in ds.Tables[1].Columns)

  {

    DataGridViewColumn col = null;

    if (dc.ColumnName == "Credit")

      col = new DataGridViewCheckBoxColumn();

    else

      col = new DataGridViewTextBoxColumn();

    col.AutoSizeMode = DataGridViewAutoSizeColumnMode.DisplayedCells;

    col.DataPropertyName = dc.ColumnName;

    col.HeaderText = dc.ColumnName;

    grid.Columns.Add(col);

  }

  grid.DefaultCellStyle.SelectionBackColor = Color.LightSteelBlue;

  grid.DefaultCellStyle.SelectionForeColor = Color.Black;

  grid.AlternatingRowsDefaultCellStyle.BackColor = Color.FromArgb(200,255,200);

Заметьте, что для колонки Credit (зачет) вместо объекта DataGridViewTextBoxColumn, мы используем объект класса DataGridViewCheckBoxColumn. В MSDN найдите все классы, производные от DataGridViewColumn и проанализируйте их функциональность. Можно добавить форматирование колонки с датой экзамена.

if (dc.ColumnName == "Date")

  col.DefaultCellStyle.Format = "d";

Отладьте приложение так, чтобы оно позволяло работать с данными двух таблиц. Пока пусть оба компонента DataGridView отображают все данные, связанных с ними таблиц.

Бывают случаи, когда создают DataRelation и отказываются от создания ForeignKeyConstraint. Если вы хотите в отобразить данные двух таблиц Клиенты и Заказы, но запретить пользователю редактировать их, то объект ForeignKeyConstraint не нужен, так как целостность данных не может быть нарушена пользователем. В то же впемя объект DataRelation нужен, так как он используется механизмом DataBinding для синхронизации отображения данных. Суть синхронизации состоит в том, что отображаются не все заказы, а заказы только одного, активного в данный момент клиента.

Автоматическая навигация по записям связанной таблицы