DataRelationクラス

コンストラクタ

public DataRelation (
    string relationName,                 // DataRelationの名前
    System.Data.DataColumn parentColumn, // 関連の親の列
    System.Data.DataColumn childColumn   // 関連の子の列
    );
DataRelation(String, DataColumn, DataColumn) - DataRelation Constructor (System.Data) | Microsoft Learn

relationNameをnullまたは空文字列とすると、DataRelationCollectionに追加したときに"Relation1"のような既定の名前が与えられます。

DataSetに追加していないテーブルの列を指定すると、「親の列または子の列が DataSet にない場合は、DataRelation を作成できません。」としてInvalidConstraintExceptionが投げられます。

DataSet dataSet = new DataSet();
DataTable tableA = dataSet.Tables.Add("parent");
DataTable tableB = dataSet.Tables.Add("child");

tableA.Columns.Add("col1");
tableA.Columns.Add("id");

tableB.Columns.Add("id");
tableB.Columns.Add("col2");


tableA.Rows.Add("val1", "10");
tableA.Rows.Add("val2", "20");

tableB.Rows.Add("20", "val3");


DataRelation relation = new DataRelation(
    "rel",
    tableA.Columns["id"],
    tableB.Columns["id"]);
relation.Nested = true;

dataSet.Relations.Add(relation);

このDataSetに対してWriteXml()を呼び出すと、

dataSet.WriteXml("sample.xml");
dataSet.WriteXmlSchema("sample.xsd");

次のように出力されます。

<?xml version="1.0" standalone="yes"?>
<NewDataSet>
  <parent>
    <col1>val1</col1>
    <id>10</id>
  </parent>
  <parent>
    <col1>val2</col1>
    <id>20</id>
    <child>
      <id>20</id>
      <col2>val3</col2>
    </child>
  </parent>
</NewDataSet>
<?xml version="1.0" standalone="yes"?>
<xs:schema id="NewDataSet" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
  <xs:element name="NewDataSet" msdata:IsDataSet="true" msdata:UseCurrentLocale="true">
    <xs:complexType>
      <xs:choice minOccurs="0" maxOccurs="unbounded">
        <xs:element name="parent">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="col1" type="xs:string" minOccurs="0" />
              <xs:element name="id" type="xs:string" minOccurs="0" />
              <xs:element name="child" minOccurs="0" maxOccurs="unbounded">
                <xs:complexType>
                  <xs:sequence>
                    <xs:element name="id" type="xs:string" minOccurs="0" />
                    <xs:element name="col2" type="xs:string" minOccurs="0" />
                  </xs:sequence>
                </xs:complexType>
              </xs:element>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
      </xs:choice>
    </xs:complexType>
    <xs:unique name="Constraint1">
      <xs:selector xpath=".//parent" />
      <xs:field xpath="id" />
    </xs:unique>
    <xs:keyref name="rel" refer="Constraint1" msdata:IsNested="true">
      <xs:selector xpath=".//child" />
      <xs:field xpath="id" />
    </xs:keyref>
  </xs:element>
</xs:schema>

またRelationが設定されたテーブルへは、次のようにアクセスできます。

DataRow[] rows0 = tableA.Rows[0].GetChildRows(relation);
DataRow[] rows1 = tableA.Rows[1].GetChildRows(relation);

int length0 = rows0.Length; // 0
int length1 = rows1.Length; // 1

object item0 = rows1[0][0]; // 20
object item1 = rows1[0][1]; // "val3"

プロパティ

プロパティ 内容
string RelationName Relationの名前
bool Nested trueならば、ネストされている。XMLとして書き出すときに作用する。既定はfalse
DataTable ParentTable このRelationの親テーブル
DataTable ChildTable このRelationの子テーブル
DataColumn[] ParentColumns このRelationの親の列
DataColumn[] ChildColumns このRelationの子の列
ForeignKeyConstraint ChildKeyConstraint RelationのForeignKeyConstraint
UniqueConstraint ParentKeyConstraint Relationの親列が唯一であることを保証するUniqueConstraint
     
Properties - DataRelation Class (System.Data) | Microsoft Learn

次のようにRelationが設定されたDataTableのDataRelationは、次の値となります。

DataSet dataSet = new DataSet();
DataTable tableA = dataSet.Tables.Add("tableA");
DataTable tableB = dataSet.Tables.Add("tableB");

DataColumn columnA = tableA.Columns.Add("columnA");
DataColumn columnB = tableB.Columns.Add("columnB");

DataRelation relation = dataSet.Relations.Add(columnA, columnB);


string name      = relation.RelationName; // "Relation1"
DataTable table1 = relation.ParentTable;  // {tableA}
DataTable table2 = relation.ChildTable;   // {tableB}

DataColumn[] columns1 = relation.ParentColumns; // {columnA}
DataColumn[] columns2 = relation.ChildColumns;  // {columnB}

Nested

パフォーマンスを優先するならば、trueとします。DataRelation の入れ子化 - ADO.NET | Microsoft Learn

これがtrueのとき、

  • 親テーブルの列のColumnNameと子テーブルのTableNameが一致すると「'***' という列が既にこの DataTable に属しています : 入れ子されたテーブル名を同じ名前に設定できません。」としてDuplicateNameExceptionが投げられる Remarks - DataRelation.Nested Property (System.Data) | Microsoft Learn
  • 親テーブルのWriteXml()ではネストされて出力され、子テーブルでは何も出力されなくなる
  • 子テーブルのWriteXmlSchema()を呼び出すと「オブジェクト参照がオブジェクト インスタンスに設定されていません。」としてNullReferenceExceptionが投げられる

これがfalseのとき、

  • WriteXmlSchema()で書き出したXMLをReadXmlSchema()で読み込むと、DataSet.Relationsの要素が逆順となる

Nestedの有効/無効で、

DataSet dataSet = new DataSet();
DataTable tableA = dataSet.Tables.Add("A");
DataTable tableB = dataSet.Tables.Add("B");

DataColumn columnA = tableA.Columns.Add("id");
DataColumn columnB = tableB.Columns.Add("id");

DataRelation relation1 = dataSet.Relations.Add(columnA, columnB);
dataSet.WriteXmlSchema("sample1.xsd");

relation1.Nested = true;
dataSet.WriteXmlSchema("sample2.xsd");

その出力に下表のような相違があります。

Nestedの値
false true
<?xml version="1.0" standalone="yes"?>
<xs:schema id="NewDataSet" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
  <xs:element name="NewDataSet" msdata:IsDataSet="true" msdata:UseCurrentLocale="true">
    <xs:complexType>
      <xs:choice minOccurs="0" maxOccurs="unbounded">
        <xs:element name="A">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="id" type="xs:string" minOccurs="0" />
            </xs:sequence>
          </xs:complexType>
        </xs:element>
        <xs:element name="B">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="id" type="xs:string" minOccurs="0" />
            </xs:sequence>
          </xs:complexType>
        </xs:element>
      </xs:choice>
    </xs:complexType>
    <xs:unique name="Constraint1">
      <xs:selector xpath=".//A" />
      <xs:field xpath="id" />
    </xs:unique>
    <xs:keyref name="Relation1" refer="Constraint1">
      <xs:selector xpath=".//B" />
      <xs:field xpath="id" />
    </xs:keyref>
  </xs:element>
</xs:schema>
<?xml version="1.0" standalone="yes"?>
<xs:schema id="NewDataSet" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
  <xs:element name="NewDataSet" msdata:IsDataSet="true" msdata:UseCurrentLocale="true">
    <xs:complexType>
      <xs:choice minOccurs="0" maxOccurs="unbounded">
        <xs:element name="A">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="id" type="xs:string" minOccurs="0" />
              <xs:element name="B" minOccurs="0" maxOccurs="unbounded">
                <xs:complexType>
                  <xs:sequence>
                    <xs:element name="id" type="xs:string" minOccurs="0" />
                  </xs:sequence>
                </xs:complexType>
              </xs:element>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
      </xs:choice>
    </xs:complexType>
    <xs:unique name="Constraint1">
      <xs:selector xpath=".//A" />
      <xs:field xpath="id" />
    </xs:unique>
    <xs:keyref name="Relation1" refer="Constraint1" msdata:IsNested="true">
      <xs:selector xpath=".//B" />
      <xs:field xpath="id" />
    </xs:keyref>
  </xs:element>
</xs:schema>

ChildKeyConstraint

Relationが設定されたテーブルへの影響は、このForeignKeyConstraintによって決定されます。

Microsoft Learnから検索