DiffGrams

DiffGram 是用于标识数据元素的当前和原始版本的 XML 格式。 DataSet 使用 DiffGram 格式来加载和保持其内容,并将其内容序列化,以便通过网络连接来进行传输。 当 DataSet 以 DiffGram 形式来编写时,它会为 DiffGram 填充所有必要的信息,以便精确地重新创建 DataSet 的内容(但不包括其架构),其中包括 Original 和 Current 行版本、行错误信息以及行顺序的列值。

当从 XML Web services 发送和检索 DataSet 时,将隐式地使用 DiffGram 格式。 此外,当使用 ReadXml 方法从 XML 加载 DataSet 的内容时,或当使用 WriteXml 方法以 XML 编写 DataSet 的内容时,可以指定内容作为 DiffGram 读取或写入。 有关详细信息,请参阅 从 XML 加载数据集 和将 数据集内容编写为 XML 数据

虽然 DiffGram 格式主要由 .NET Framework 用作 DataSet 内容的序列化格式,但也可以使用 DiffGram 来修改 Microsoft SQL Server 数据库中表的数据。

通过将所有表的内容写入到 <diffgram> 元素中可生成 Diffgram。

生成 Diffgram

  1. 生成根表(即没有任何父级的表)的列表。

  2. 对于列表中每个表及其子代,在 Diffgram 的第一部分中写出所有行的当前版本。

  3. 对于 DataSet 中的每个表,在 Diffgram 的 <before> 部分中写出所有行的原始版本(如果有)。

  4. 对于有错误的行,在 Diffgram 的 <errors> 部分中写入错误内容。

将按照从 XML 文件的开头到结尾的顺序处理 Diffgram。

处理 Diffgram

  1. 处理包含行当前版本的 Diffgram 的第一部分。

  2. 处理包含已修改行和已删除行的原始行版本的第二部分或 <before> 部分。

    备注

    如果某行标记为已删除,则删除操作还可删除该行的子代,具体取决于当前 CascadeDataSet 属性。

  3. 处理 <errors> 部分。 为本部分中各项的指定行和列设置错误信息。

备注

如果将 XmlWriteMode 设置为 Diffgram,则目标 DataSet 和原始 DataSet 的内容可能会不同。

DiffGram 格式

DiffGram 格式可分为三部分:当前数据、原始(或“before”)数据和错误部分,如下面的示例中所示。

<?xml version="1.0"?>  
<diffgr:diffgram
         xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"  
         xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1"  
         xmlns:xsd="http://www.w3.org/2001/XMLSchema">  
  
   <DataInstance>  
   </DataInstance>  
  
  <diffgr:before>  
  </diffgr:before>  
  
  <diffgr:errors>  
  </diffgr:errors>  
</diffgr:diffgram>  

DiffGram 格式由以下数据块组成:

<DataInstance>
DataInstance 表示此元素的名称,用于在该文档中提供解释。 DataInstance 元素表示 DataSetDataTable 的行。 不过,该元素所包含的并不是 DataInstance,而是 DataSetDataTable 的名称。 此 DiffGram 格式块包含当前数据(无论是否经过修改)。 已修改的元素或行用 diffgr:hasChanges 批注来标识。

<diffgr:before>
此 DiffGram 格式块包含行的原始版本。 使用 diffgr:id 批注将该块中的元素与 DataInstance 块中的元素进行匹配。

<diffgr:errors>
此 DiffGram 格式块包含 DataInstance 块中特定行的错误信息。 使用 diffgr:id 批注将该块中的元素与 DataInstance 块中的元素进行匹配。

DiffGram 批注

DiffGram 使用一些批注来使来自不同 DiffGram 块的元素相关,这些块表示 DataSet 中的不同行版本或错误信息。

下表描述在 DiffGram 命名空间 urn:schemas-microsoft-com:xml-diffgram-v1 中定义的 DiffGram 批注。

Annotation 说明
id 用于将 <diffgr:before> 和 <diffgr:errors> 块中的元素与 <DataInstance> 块中的元素配对。 带有 diffgr:id 批注的值的格式为 [TableName][RowIdentifier]。 例如:<Customers diffgr:id="Customers1">
parentId 标识 <DataInstance> 块中的哪个元素是当前元素的父元素。 带有 diffgr:parentId 批注的值的格式为 [TableName][RowIdentifier]。 例如:<Orders diffgr:parentId="Customers1">
hasChanges <DataInstance> 块中的行标识为已修改。 hasChanges 批注可以具有以下两个值之一:

inserted
标识 Added 行。

已修改
标识包含 <diffgr:before> 块中 Original 行版本的 Modified 行。 请注意,Deleted 行将包含 <diffgr:before> 块中的 Original 行版本,但 <DataInstance> 块中将不存在批注元素。
hasErrors 用 RowError 标识 <DataInstance> 块中的行。 错误元素放置在 <diffgr:errors> 块中。
错误 包含 <diffgr:errors> 块中特定元素的 RowError 的文本。

当以 DiffGram 格式读写 DataSet 的内容时,还包含附加的批注。 下表描述在 urn:schemas-microsoft-com:xml-msdata 命名空间中定义的三个附加批注。

Annotation 说明
RowOrder 保留原始数据的行顺序并标识特定 DataTable 中行的索引。
Hidden 将列标识为 ColumnMapping 属性设置为 MappingType.Hidden。 该属性以 msdata:hidden[ColumnName]="value" 格式编写。 例如:<Customers diffgr:id="Customers1" msdata:hiddenContactTitle="Owner">

请注意,只有当隐藏列包含数据时才以 DiffGram 属性的形式来编写隐藏列。 否则会忽视优先级。

DiffGram 示例

下面是 DiffGram 格式的示例。 该示例显示对表行的更新在提交更改之前的结果。 CustomerID 为“ALFKI”的行已被修改,但尚未更新。 因此,<DataInstance> 块中有一个 diffgr:id 为“Customers1”的 Current 行,diffgr:before> 块中有一个 <diffgr:id> 为“Customers1”的 Original 行。 CustomerID 为“ANATR”的行包含一个 RowError,因此它带有 diffgr:hasErrors="true" 批注并且在 <diffgr:errors> 块中有一个相关的元素。

<diffgr:diffgram xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1">  
  <CustomerDataSet>  
    <Customers diffgr:id="Customers1" msdata:rowOrder="0" diffgr:hasChanges="modified">  
      <CustomerID>ALFKI</CustomerID>  
      <CompanyName>New Company</CompanyName>  
    </Customers>  
    <Customers diffgr:id="Customers2" msdata:rowOrder="1" diffgram:hasErrors="true">  
      <CustomerID>ANATR</CustomerID>  
      <CompanyName>Ana Trujillo Emparedados y Helados</CompanyName>  
    </Customers>  
    <Customers diffgr:id="Customers3" msdata:rowOrder="2">  
      <CustomerID>ANTON</CustomerID>  
      <CompanyName>Antonio Moreno Taquera</CompanyName>  
    </Customers>  
    <Customers diffgr:id="Customers4" msdata:rowOrder="3">  
      <CustomerID>AROUT</CustomerID>  
      <CompanyName>Around the Horn</CompanyName>  
    </Customers>  
  </CustomerDataSet>  
  <diffgr:before>  
    <Customers diffgr:id="Customers1" msdata:rowOrder="0">  
      <CustomerID>ALFKI</CustomerID>  
      <CompanyName>Alfreds Futterkiste</CompanyName>  
    </Customers>  
  </diffgr:before>  
  <diffgr:errors>  
    <Customers diffgr:id="Customers2" diffgr:Error="An optimistic concurrency violation has occurred for this row."/>  
  </diffgr:errors>  
</diffgr:diffgram>  

请参阅