When making changes to a
DataSet
, it is often useful to keep a record of
the changes. That way you can make a set of related changes on the
client machine, then transmit just the changes back to the server.
This technique saves network time, because the changes are all
transmitted at once, and it saves bandwidth, because only the changes
are transmitted.
You could add another line of code to Example 11-8 to
see that the DataSet
maintains a
“before” and
“after” view of the data. Add this
line before the Update( )
statement:
dataSet.WriteXml(Console.Out, XmlWriteMode.DiffGram);
And you’ll see the following output when you run the program:
<diffgr:diffgram xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns:diffgr= "urn:schemas-microsoft-com:xml-diffgram-v1"> <AngusHardware> <coupons diffgr:id="coupons1" msdata:rowOrder="0" diffgr:hasChanges="modified"> <coupon_code>077GH </coupon_code> <discount_amount>15</discount_amount> <discount_type>0</discount_type> <expiration_date>2002-11-09T14:17:41.6372544-05:00</expiration_date> </coupons> <coupons diffgr:id="coupons2" msdata:rowOrder="1"> <coupon_code>665RQ </coupon_code> <discount_amount>15</discount_amount> <discount_type>0</discount_type> <expiration_date>2002-11-30T00:00:00.0000000-05:00</expiration_date> </coupons> <coupons diffgr:id="coupons3" msdata:rowOrder="2"> <coupon_code>81BIN </coupon_code> <discount_amount>10</discount_amount> <discount_type>1</discount_type> <expiration_date>2003-01-31T00:00:00.0000000-05:00</expiration_date> </coupons> <coupons diffgr:id="coupons4" msdata:rowOrder="3"> <coupon_code>99GGY </coupon_code> <discount_amount>5</discount_amount> <discount_type>0</discount_type> <expiration_date>2002-12-31T00:00:00.0000000-05:00</expiration_date> </coupons> </AngusHardware> <diffgr:before> <coupons diffgr:id="coupons1" msdata:rowOrder="0"> <coupon_code>077GH </coupon_code> <discount_amount>15</discount_amount> <discount_type>0</discount_type> <expiration_date>2002-11-09T14:01:24.1830000-05:00</expiration_date> </coupons> </diffgr:before> </diffgr:diffgram>
This is the DiffGram
, and it shows the current
state (“after”) of the data in the
DataSet
, as well as a
“before” state in the
diffgr:before
element.
The DiffGram
is an XML
document that has three sections. The first, the current data
instance, is represented by an XML element whose name matches the
DataSet
name; in this case,
that’s the AngusHardware
element.
Under the data instance element, the current state of each row in
each of the DataSet
’s
DataTable
s is serialized as a simple XML element.
The second section,
diffgr:before
, lists the values of any rows that
have changed before the change. And the third section,
diffgr:errors
, shows any errors that occurred
during the generation of the DiffGram
.
Example 11-9 shows the general format of the
DiffGram
.
<diffgr:diffgram xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns:diffgr= "urn:schemas-microsoft-com:xml-diffgram-v1"> <DataSetName
> <DataTableName
diffgr:id="DataTableName
1" msdata:rowOrder="0" diffgr:hasChanges="modified"> <DataColumnName
>DataColumnValue
</DataColumnName
> <DataColumnName
>DataColumnValue
</DataColumnName
> ... </DataTableName
> <DataTableName
diffgr:id="DataTableName
2" msdata:rowOrder="1"> <DataColumnName
>DataColumnValue
</DataColumnName
> <DataColumnName
>DataColumnValue
</DataColumnName
> ... </DataTableName
> </DataSetName
> <diffgr:before> <DataTableName
diffgr:id="DataTableName
n
" msdata:rowOrder="DataRow
n
"> <DataColumnName
>DataColumnValue
</DataColumnName
> <DataColumnName
>DataColumnValue
</DataColumnName
> ... </DataTableName
> ... </diffgr:before> <diffgr:errors> <DataTableName
diffgr:id="DataTableName
n
" diffgr:Error="ErrorText
"/> ... </diffgr:errors> </diffgr:diffgram>
The
following details the DiffGram
elements,
attributes, and content:
diffgr:diffgram
This is the root element of the DiffGram
. It uses
two namespaces, prefixed with msdata
and
diffgr
, respectively.
DataSetName
This element’s name is the name of the
DataSet
. All the current values of each
DataTable
’s
DataRow
s are included within this element.
DataTableName
This element’s name is the name of the
DataTable
, and the element represents an
individual DataRow
.
DataColumnName
This element represents a DataColumn
within a
single DataRow
. Its content is the current value
of the column for that row.
diffgr:before
This is the element that contains the previous values of any changed
DataRow
s. Its content represents the previous
value of a DataRow
instance with the matching
value of the
DataTableName
’s
diffgr:id
attribute.
diffgr:errors
This is the element that contains any error messages. Its
diffgr:Error
attribute contains the error message
for the DataRow
instance with the matching value
of the DataTableName
’s
diffgr:id
attribute.
diffgr:id
This attribute represents a unique identifier for a
DataRow
. Its content is made up of the
DataTable
name and a sequential number. It is used
to map the current value of a DataRow
to the
previous value in the diffgr:before
section or to
any errors in the diffgr:errors
section.
msdata:rowOrder
This attribute indicates the order of the DataRow
within the DataTable
.
diffgr:hasChanges
This attribute is used to indicate whether the current value of a
DataRow
represents any changes, in which case the
previous values will be listed in the
diffgr:before
section.
diffgr:hasChanges
can have the value
inserted
, modified
, or
descent
:
inserted
The value inserted
identifies an element which has
been added
modified
The value modified
identifies an element that has
been modified
descent
The value descent
identifies an element where one
or more children from a parent-child relationship have been modified
diffgr:Error
This attribute’s content is a textual error message
describing an error that arose while attempting to change the data in
a DataSet
.
Although the DiffGram
is used internally by .NET
for remoting and web services, it can also be used by any external
system that needs to communicate database changes to a .NET
DataSet
.
3.145.8.8