DataSet 的关系结构(即架构)由表、列、约束和关系组成。当从 XML 中加载 DataSet 时,可以预定义架构,或者可以从所加载的 XML 显式(或通过推断)创建架构。有关从 XML 中加载 DataSet 的架构和内容的更多信息,请参阅从 XML 中加载 DataSet 和从 XML 中加载 DataSet 架构信息。
如果正在从 XML 创建 DataSet 的架构,首选方法是使用 XML 架构定义语言 (XSD)(在从 XML 架构 (XSD) 生成 DataSet 关系结构中描述)或 XML 简化数据 (XDR) 来显式指定架构。如果 XML中没有可用的 XML 架构或 XDR 架构,则可以从 XML 元素和属性的结构推断 DataSet 的架构。
本节通过显示 XML 元素和属性及其结构以及生成的推断 DataSet 架构来描述推断 DataSet 架构的规则。
指定要推断的属性
并非所有出现在 XML 文档中的属性都应包含在推理过程中。由命名空间限定的属性可以包含对 XML 文档重要但对 DataSet 架构不重要的元数据。使用 DataSet.InferXmlSchema,您可以设置要在推理过程中忽略的特定命名空间。有关更多信息,请参阅从 XML 中加载 DataSet 架构信息。
本节内容
DataSet 架构推理过程概述:提供从 XML 推断 DataSet 架构的规则的简要概述。
| 推理过程首先从 XML
文档中确定将哪些元素推断为表。从剩余的 XML
中,推理过程将确定这些表的列。对于嵌套表,推理过程会生成嵌套的
DataRelation 和 ForeignKeyConstraint 对象。
下面是推理规则的简要概述:
|
推断表:描述被推断为 DataSet 中的表的 XML 元素。
| 当从 XML 文档推断 DataSet 的架构时,ADO.NET
首先会确定哪些 XML 元素表示表。以下 XML 结构将为 DataSet
架构生成一个表。
具有属性的元素 在其中指定了属性的元素将生成推断表。例如,考虑以下 XML: <DocumentElement> 推理过程将生成名为“Element1”的表。 数据集:DocumentElement 表:Element1
具有子元素的元素 具有子元素的元素将生成推断表。例如,考虑以下 XML: <DocumentElement> 推理过程将生成名为“Element1”的表。 数据集:DocumentElement 表:Element1
如果文档元素或根元素具有将被推断为列的属性或子元素,它将生成推断表。如果文档元素不具有将被推断为列的属性和子元素,则该元素将被推断为 DataSet。例如,考虑以下 XML: <DocumentElement> 推理过程将生成名为“DocumentElement”的表。 数据集:NewDataSet 表:DocumentElement
或者,考虑以下 XML: <DocumentElement> 推理过程将生成一个名为“DocumentElement”的 DataSet,它包含名为“Element1”的表。 数据集:DocumentElement 表:Element1
重复元素 重复的元素将生成单个推断表。例如,考虑以下 XML: <DocumentElement> 推理过程将生成名为“Element1”的表。 数据集:DocumentElement 表:Element1
|
推断列:描述被推断为表列的 XML 元素和属性。
| 当从 XML 文档推断 DataSet 的架构时,ADO.NET
首先确定将哪些元素推断为表,然后从剩余的 XML
元素和属性中确定为这些表推断出哪些列。由于数据类型信息仅在内联架构中才可用,所以推断列的数据类型为
System.String。以下 XML 结构将生成表列。
属性 正如推断表中的定义,具有属性的元素将被推断为表。然后,该元素的属性将被推断为该表的列。这些列的 ColumnMapping 属性将设置为 MappingType.Attribute,以确保列名称将在架构写回 XML 时被写为属性。这些属性的值在表的一行中进行排序。例如,考虑以下 XML: <DocumentElement> 推理过程将生成一个名为“Element1”的表,它包含两个列:“attr1”和“attr2”。这两个列的 ColumnMapping 属性都将设置为 MappingType.Attribute。 数据集:DocumentElement 表:Element1
不具有属性或子元素的元素 如果元素不具有子元素或属性,它将被推断为列。该列的 ColumnMapping 属性将设置为 MappingType.Element。子元素的文本存储在表的一行中。例如,考虑以下 XML: <DocumentElement> 推理过程将生成一个名为“Element1”的表,它包含两个列:“ChildElement1”和“ChildElement2”。这两个列的 ColumnMapping 属性将设置为 MappingType.Element。 数据集:DocumentElement 表:Element1
|
推断关系:描述为嵌套的推断表创建的 DataRelation 和 ForeignKeyConstraint 对象。
| 如果被推断为表的元素具有一个同样被推断为表的子元素,则将在这两个表之间创建
DataRelation。一个名为“ParentTableName_Id”的新列将添加到为父元素创建的表以及为子元素创建的表中。该标识列的
ColumnMapping 属性将设置为 MappingType.Hidden。该列将成为父表的自动递增主键,并将用于两个表之间的
DataRelation。所添加的标识列的数据类型将为 System.Int32,这与其他所有推断的列的数据类型(System.String)不同。还将使用父表和子表中的新列来创建一个
DeleteRule = Cascade 的 ForeignKeyConstraint。
例如,考虑以下 XML: <DocumentElement> 推理过程将生成两个表:“Element1”和“ChildElement1”。 “Element1”表包含两个列:“Element1_Id”和“ChildElement2”。“Element1_Id”列的 ColumnMapping 属性将设置为 MappingType.Hidden。“ChildElement2”列的 ColumnMapping 属性将设置为 MappingType.Element。“Element1_Id”列将设置为“Element1”表的主键。 “ChildElement1”表将包含三个列:“attr1”、“attr2”和“Element1_Id”。“attr1”列和“attr2”列的 ColumnMapping 属性将设置为 MappingType.Attribute。“Element1_Id”列的 ColumnMapping 属性将设置为 MappingType.Hidden。 DataRelation 和 ForeignKeyConstraint 将使用两个表中的“Element1_Id”列来创建。 数据集:DocumentElement 表:Element1
表:ChildElement1
数据关系 (DataRelation):Element1_ChildElement1 父表:Element1 父列:Element1_Id 子表:ChildElement1 子列:Element1_Id 嵌套 (Nested):True 外键约束 (ForeignKeyConstraint):Element1_ChildElement1 列:Element1_Id 父表:Element1 子表:ChildElement1 删除规则:级联 (DeleteRule: Cascade) 接受拒绝规则:无 (AcceptRejectRule: None) |
推断元素文本:描述为 XML 元素中的文本创建的列,并解释何时会忽略 XML 元素中的文本。
| 如果元素包含文本但不包含被推断为表的子元素(如具有属性或重复元素的元素),一个名为“TableName_Text”的新列将添加到为该元素推断的表中。该元素中包含的文本将添加到此表中的一行,并存储在新列中。新列的
ColumnMapping 属性将设置为 MappingType.SimpleContent。
例如,考虑以下 XML: <DocumentElement> 推理过程将生成一个名为“Element1”的表,它包含两个列:“attr1”和“Element1_Text”。“attr1”的 ColumnMapping 属性将设置为 MappingType.Attribute。“Element1_Text”列的 ColumnMapping 属性将设置为 MappingType.SimpleContent。 数据集:DocumentElement 表:Element1
如果某元素包含文本,并且还具有包含文本的子元素,则不会将列添加到表中来存储该元素所包含的文本。该元素中包含的文本将被忽略,但子元素中的文本将包含在表的一行中。例如,考虑以下 XML: <Element1> 推理过程将生成一个名为“Element1”的表,它包含一个名为“ChildElement1”的列。“ChildElement1”元素的文本将包含在表的一行中。其他文本则将被忽略。“ChildElement1”列的 ColumnMapping 属性将设置为 MappingType.Element。 数据集:DocumentElement 表:Element1
|
推断限制:讨论架构推断的限制。
| 从 XML 推断 DataSet
的过程不是确定性的,因为根据每个文档中 XML
元素的不同,具有相同预期架构的不同 XML
文档实例可能会生成不同的架构。例如,考虑以下 XML
文档:
Document1: <DocumentElement> Document2: <DocumentElement> 对于“Document1”,由于“Element1”是重复元素,推理过程将生成一个名为“DocumentElement”的 DataSet 和一个名为“Element1”的表。 数据集:DocumentElement 表:Element1
但是,对于“Document2”,推理过程将生成一个名为“NewDataSet”的 DataSet 和一个名为“DocumentElement”的表。由于“Element1”不具有属性和子元素,它将被推断为列。 数据集:NewDataSet 表:DocumentElement
这两个 XML 文档可能本应生成相同的架构,但根据每个文档中包含的不同元素,推理过程生成了极不相同的结果。 若要避免在从 XML 文档生成架构时可能出现的差异,建议在从 XML 中加载 DataSet 时使用 XML 架构定义语言 (XSD) 或 XML 简化数据 (XDR) 显式地指定架构。有关使用 XML 架构显式指定 DataSet 架构的更多信息,请参阅从 XML 架构 (XSD) 生成 DataSet 关系结构。 |