Rovan

      一个犁牛半块田,收也凭天,荒也凭天, 清茶淡饭饱三餐,早也香甜,晚也香甜, 布衣得暖胜丝绵,长也可穿,短也可穿, 草舍茅屋有几间,行也安然,待也安然, 雨过天青驾小船,鱼在一边,酒在一边, 夜归儿女话灯前,今也有言,古也有言, 日上三竿我独眠,请是神仙,我是神仙.

首页 新随笔 联系 订阅 管理

DataSet 的关系结构(即架构)由表、列、约束和关系组成。当从 XML 中加载 DataSet 时,可以预定义架构,或者可以从所加载的 XML 显式(或通过推断)创建架构。有关从 XML 中加载 DataSet 的架构和内容的更多信息,如果正在从 XML 创建 DataSet 的架构,首选方法是使用 XML 架构定义语言 (XSD)或 XML 简化数据 (XDR) 来显式指定架构。如果 XML 中没有可用的 XML 架构或 XDR 架构,则可以从 XML 元素和属性的结构推断 DataSet 的架构。

本节通过显示 XML 元素和属性及其结构以及生成的推断 DataSet 架构来描述推断 DataSet 架构的规则。

指定要推断的属性

并非所有出现在 XML 文档中的属性都应包含在推理过程中。由命名空间限定的属性可以包含对 XML 文档重要但对 DataSet 架构不重要的元数据。使用 DataSet.InferXmlSchema,您可以设置要在推理过程中忽略的特定命名空间。

DataSet 架构推理过程概述

推理过程首先从 XML 文档中确定将哪些元素推断为表。从剩余的 XML 中,推理过程将确定这些表的列。对于嵌套表,推理过程会生成嵌套的 DataRelationForeignKeyConstraint 对象。

下面是推理规则的简要概述:

  • 具有属性的元素会被推断为表。
  • 具有子元素的元素会被推断为表。
  • 重复的元素会被推断为单个表。
  • 如果文档元素或根元素不具有将被推断为列的属性和子元素,则该元素将被推断为 DataSet。否则,文档元素会被推断为表。
  • 属性会被推断为列。
  • 不具有属性或子元素且不重复的元素会被推断为列。
  • 如果元素被推断为表,而这些表嵌套在同样被推断为表的其他元素中,则将在两个表之间创建嵌套的 DataRelation。两个表中都将添加一个名为“TableName_Id”的新主键列,该列由 DataRelation 来使用。两个表之间的 ForeignKeyConstraint 使用“TableName_Id”列来创建。
  • 对于被推断为表的元素和包含文本但不包含子元素的元素,将为每个元素的文本创建一个名为“TableName_Text”的新列。如果元素被推断为表并包含文本和子元素,则将忽略文本。

推断表

当从 XML 文档推断 DataSet 的架构时,ADO.NET 首先会确定哪些 XML 元素表示表。以下 XML 结构将为 DataSet 架构生成一个表。

具有属性的元素

在其中指定了属性的元素将生成推断表。例如,考虑以下 XML:

<DocumentElement>
<Element1 attr1="value1"/>
<Element1 attr1="value2">Text1</Element1>
</DocumentElement>

推理过程将生成名为“Element1”的表。

数据集:DocumentElement

表:Element1

attr1 Element1_Text
value1    
value2 Text1

具有子元素的元素

具有子元素的元素将生成推断表。例如,考虑以下 XML:

<DocumentElement>
<Element1>
<ChildElement1>Text1</ChildElement1>
</Element1>
</DocumentElement>

推理过程将生成名为“Element1”的表。

数据集:DocumentElement

表:Element1

ChildElement1
Text1

如果文档元素或根元素具有将被推断为列的属性或子元素,它将生成推断表。如果文档元素不具有将被推断为列的属性和子元素,则该元素将被推断为 DataSet。例如,考虑以下 XML:

<DocumentElement>
<Element1>Text1</Element1>
<Element2>Text2</Element2>
</DocumentElement>

推理过程将生成名为“DocumentElement”的表。

数据集:NewDataSet

表:DocumentElement

Element1 Element2
Text1 Text2

或者,考虑以下 XML:

<DocumentElement>
<Element1 attr1="value1" attr2="value2"/>
</DocumentElement>

推理过程将生成一个名为“DocumentElement”的 DataSet,它包含名为“Element1”的表。

数据集:DocumentElement

表:Element1

attr1 attr2
value1 value2

重复元素

重复的元素将生成单个推断表。例如,考虑以下 XML:

<DocumentElement>
<Element1>Text1</Element1>
<Element1>Text2</Element1>
</DocumentElement>

推理过程将生成名为“Element1”的表。

数据集:DocumentElement

表:Element1

Element1_Text
Text1
Text2

推断列

当从 XML 文档推断 DataSet 的架构时,ADO.NET 首先确定将哪些元素推断为表,然后从剩余的 XML 元素和属性中确定为这些表推断出哪些列。由于数据类型信息仅在内联架构中才可用,所以推断列的数据类型为 System.String。以下 XML 结构将生成表列。

属性

正如推断表中的定义,具有属性的元素将被推断为表。然后,该元素的属性将被推断为该表的列。这些列的 ColumnMapping 属性将设置为 MappingType.Attribute,以确保列名称将在架构写回 XML 时被写为属性。这些属性的值在表的一行中进行排序。例如,考虑以下 XML:

<DocumentElement>
<Element1 attr1="value1" attr2="value2"/>
</DocumentElement>

推理过程将生成一个名为“Element1”的表,它包含两个列:“attr1”和“attr2”。这两个列的 ColumnMapping 属性都将设置为 MappingType.Attribute

数据集:DocumentElement

表:Element1

attr1 attr2
value1 value2

不具有属性或子元素的元素

如果元素不具有子元素或属性,它将被推断为列。该列的 ColumnMapping 属性将设置为 MappingType.Element。子元素的文本存储在表的一行中。例如,考虑以下 XML:

<DocumentElement>
<Element1>
<ChildElement1>Text1</ChildElement1>
<ChildElement2>Text2</ChildElement2>
</Element1>
</DocumentElement>

推理过程将生成一个名为“Element1”的表,它包含两个列:“ChildElement1”和“ChildElement2”。这两个列的 ColumnMapping 属性将设置为 MappingType.Element

数据集:DocumentElement

表:Element1

ChildElement1 ChildElement2
Text1 Text2

推断关系

如果被推断为表的元素具有一个同样被推断为表的子元素,则将在这两个表之间创建 DataRelation。一个名为“ParentTableName_Id”的新列将添加到为父元素创建的表以及为子元素创建的表中。该标识列的 ColumnMapping 属性将设置为 MappingType.Hidden。该列将成为父表的自动递增主键,并将用于两个表之间的 DataRelation。所添加的标识列的数据类型将为 System.Int32,这与其他所有推断的列的数据类型(System.String)不同。还将使用父表和子表中的新列来创建一个 DeleteRule = CascadeForeignKeyConstraint

例如,考虑以下 XML:

<DocumentElement>
<Element1>
<ChildElement1 attr1="value1" attr2="value2"/>
<ChildElement2>Text2</ChildElement2>
</Element1>
</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

DataRelationForeignKeyConstraint 将使用两个表中的“Element1_Id”列来创建。

数据集:DocumentElement

表:Element1

Element1_Id ChildElement2
0 Text2

表:ChildElement1

attr1 attr2 Element1_Id
value1 value2 0

数据关系 (DataRelation):Element1_ChildElement1

父表:Element1
父列:Element1_Id
子表:ChildElement1
子列:Element1_Id
嵌套 (Nested):True

外键约束 (ForeignKeyConstraint):Element1_ChildElement1

列:Element1_Id
父表:Element1
子表:ChildElement1
删除规则:级联 (DeleteRule: Cascade)

接受拒绝规则:无 (AcceptRejectRule: None)

推断元素文本

如果元素包含文本但不包含被推断为表的子元素(如具有属性或重复元素的元素),一个名为“TableName_Text”的新列将添加到为该元素推断的表中。该元素中包含的文本将添加到此表中的一行,并存储在新列中。新列的 ColumnMapping 属性将设置为 MappingType.SimpleContent

例如,考虑以下 XML:

<DocumentElement>
<Element1 attr1="value1">Text1</Element1>
</DocumentElement>

推理过程将生成一个名为“Element1”的表,它包含两个列:“attr1”和“Element1_Text”。“attr1”的 ColumnMapping 属性将设置为 MappingType.Attribute。“Element1_Text”列的 ColumnMapping 属性将设置为 MappingType.SimpleContent

数据集:DocumentElement

表:Element1

attr1 Element1_Text
value1 Text1

如果某元素包含文本,并且还具有包含文本的子元素,则不会将列添加到表中来存储该元素所包含的文本。该元素中包含的文本将被忽略,但子元素中的文本将包含在表的一行中。例如,考虑以下 XML:

<Element1>
Text1
<ChildElement1>Text2</ChildElement1>
Text3
</Element1>

推理过程将生成一个名为“Element1”的表,它包含一个名为“ChildElement1”的列。“ChildElement1”元素的文本将包含在表的一行中。其他文本则将被忽略。“ChildElement1”列的 ColumnMapping 属性将设置为 MappingType.Element

数据集:DocumentElement

表:Element1

ChildElement1
Text2

推断限制

从 XML 推断 DataSet 的过程不是确定性的,因为根据每个文档中 XML 元素的不同,具有相同预期架构的不同 XML 文档实例可能会生成不同的架构。例如,考虑以下 XML 文档:

Document1:

<DocumentElement>
<Element1>Text1</Element1>
<Element1>Text2</Element1>
</DocumentElement>

Document2:

<DocumentElement>
<Element1>Text1</Element1>
</DocumentElement>

对于“Document1”,由于“Element1”是重复元素,推理过程将生成一个名为“DocumentElement”的 DataSet 和一个名为“Element1”的表。

数据集:DocumentElement

表:Element1

Element1_Text
Text1
Text2

但是,对于“Document2”,推理过程将生成一个名为“NewDataSet”的 DataSet 和一个名为“DocumentElement”的表。由于“Element1”不具有属性和子元素,它将被推断为列。

数据集:NewDataSet

表:DocumentElement

Element1
Text1

这两个 XML 文档可能本应生成相同的架构,但根据每个文档中包含的不同元素,推理过程生成了极不相同的结果。

若要避免在从 XML 文档生成架构时可能出现的差异,建议在从 XML 中加载 DataSet 时使用 XML 架构定义语言 (XSD) 或 XML 简化数据 (XDR) 显式地指定架构。

posted on 2006-07-05 09:21  Ruxuan  阅读(255)  评论(0)    收藏  举报