Рассмотрим, как можно получить информацию об объекте DataTabie (Таблица данных), точнее, об ограничениях и ключах этого объекта. В предыдущем примере уже было показано, как получить доступ к объектам Data-Column объекта DataTabie (Таблица данных). Обратите внимание на использование свойства IsPrimaryKey объекта UniqueConstraint для определения, является ли ограничение первичным ключом. Следующий фрагмент взят из примера DataEditing.
pEnum = ds->Tables->GetEnumerator(); // Таблицы
while (pEnum->MoveNext() )
{
DataTabie *t =
dynamic_cast<DataTable *>(pEnum->Current);
Console::WriteLine(" {0}", t->TableName);
Console : :WriteLine ( "\tPrimary Key:")/' // Первичный ключ
for (int i = 0; i < t->PrimaryKey.Length; i++)
{
DataColumn *c = t->PrimaryKey[i]; Console::WriteLine("\t\t{0}", c->ColumnName); }
Console::WriteLine("\tConstraints:" ) ;
lEnumerator *pEnum = t->Constraints->GetEnumerator(); // Ограничения while (pEnum->MoveNext()) {
Constraint *c = // Ограничение
dynamic_cast<Constraint *>(pEnum->Current); // Ограничение
String *constraintName; // Строка // если (с - ForeignKeyConstraint) if (dynamic_cast<ForeignKeyConstraint *>(c) != 0) constraintName =
String::Concat("Foreign Key:", // Строка:: Concat ("Внешний ключ: ", c->ConstraintName);
else if (dynamic_cast<UniqueConstraint *>(c) != 0) {
UniqueConstraint *u = dynamic_cast<UniqueConstraint *>(c); if (u->IsPrimaryKey)
constraintName = "Primary Key"; // Первичный ключ else
constraintName = u->ConstraintName; } else
constraintName = "Unknown Name"; // Неизвестное имя Console::WriteLine("\t\t{0, -40}", constraintName); } }
Напечатанные программой строки приведены ниже. Обратите внимание на то, что определение связей, осуществленное нами с помощью объектов DataRelation, приводит к появлению объектов ForeignKeyConstraint в коллекции ограничений таблицы.
Первичный ключ также появляется в коллекции ограничений как объект UniqueCon-straint. Ограничения, определенные как ограничения единственности или внешние ключи, появляются в коллекции так, как ожидается.
Categories
Primary Key: Constraints:
Unique CategoryName Constraint BookCategories Primary Key:
CategoryName
LibraryofCongressNumber Constraints:
Primary Key
Foreign Key:Category->BookCategories Relation
Constraint2 Authors
Primary Key:
Authorld Constraints:
Primary Key Books
Primary Key:
ISBN Constraints:
Primary Key
Foreign Key:Authors->Books
Foreign Key:Book Category LOC->Book LOG Relation
Вот перевод этой выдачи:
Категории
Первичный ключ: Ограничения:
Ограничение единственности CategoryName Категории книг
Первичный ключ:
Название категории
Номер в Библиотеке Конгресса Ограничения:
Первичный ключ
Внешний ключ: Отношение Category-> BookCategories
Constraint2 Авторы
Первичный ключ:
Authorld Ограничения:
Первичный ключ Книги
Первичный ключ:
ISBN Ограничения:
Первичный ключ:
Внешний ключ:Авторы-> Книги
Внешний ключ: Отношение Book Category LOC->Book LOG
Обратите внимание на ограничение в таблице BookCategories (Категории книг) с именем, сгенерированным системой. Когда вы внимательно просмотрите исходный код программы, то убедитесь, что эти ограничения в ней не добавляются. Откуда же они берутся? Если бы вы просмотрели содержимое соответствующего объекта, то увидели бы, что ограничение наложено на столбец LibraryofCongressNumber. Система посчитала, что, поскольку столбец CategoryName является внешним ключом для другой таблицы, то значения в столбце LibraryOfCongressNumber должны быть уникальными.
Можно также просмотреть коллекцию связей Relations (Отношения) объекта DataSet (Набор данных). При этом можно узнать, какие таблицы являются предками, и какие именно столбцы в них участвуют в образовании связей. То же самое можно сделать и для таблиц-потомков. Приведем соответствующий фрагмент примера DataEditing.
pEnum = ds->Relations->GetEnumerator(); // Отношения
while (pEnum->MoveNext())
{
DataRelation *dr =
dynamic_cast<DataRelation *>(pEnum->Current); DataTable ^parentTable = dr->ParentTable; DataTable *childTable = dr->ChildTable; Console::WriteLine(
" Relation: {0} ", dr->RelationName); // Отношение Console::WriteLine(
ParentTable: {0, -10}", parentTable); Console::Write(" Columns: "); // Столбцы forfint j =0; j < dr->ParentColumns.Length; j++) Console::Write( // Запись
{0, -10}",
dr->ParentColumns[j]->ColumnName); Console::WriteLine(); Console::WriteLine(
ChildTable: (0, -10}", childTable);
Console::Write(" Columns: "); // Запись forfint j = 0; j < dr->ChildColumns.Length; j++) Console::Write( // Запись
{0, -10}",
dr->ChildColumns[j]->ColumnName); Console::WriteLine(); }
Программа напечатает:
Output Relations between tables in the DataSet... Relation: Category->BookCategones Relation ParentTable: Categories
Columns: Category ChildTable: BookCategories
Columns: CategoryName Relation: Book Category LOC->Book LOG Relation ParentTable: BookCategories
Columns: LibraryofCongressNumber
ChildTable: Books
Columns: LibraryofCongressNumber
А вот и перевод:
Отношения между таблицами в Наборе данных...
Отношение: Категория-> Отношение Категории книг ParentTable: Категории
Столбцы: Категория ChildTable: Категории книг
Столбцы: CategoryName Отношение: Отношение Категория книги LOC->Book LOC ParentTable: Категории книг
Столбцы: Номер в Библиотеке Конгресса ChildTable: Книги
Столбцы: Номер в Библиотеке Конгресса