The TaminoDataAdapter
class enables you to use
.NET’s DataSet
object together with Tamino XML data. The
DataSet
object is a table/column-oriented object which
is suited for disconnected working and can easily be bound to Windows Forms and
Web Forms controls. For more information about .NET datasets, see Microsoft's
.NET Framework documentation.
However, a table/column-oriented object is not appropriate for complex
XML data. For processing a list of complex XML data, and in order to get the
full benefit of Tamino’s native XML support, your application should use the
TaminoCommand
and
TaminoItemIterator
/TaminoPageIterator
objects instead (see 'Using Tamino
Cursors' and 'Iterating through Query
Results').
For processing a list of simple XML data or a list of simple subtrees of
complex XML documents, the TaminoDataAdapter
provides a
convenient option to the
TaminoItemIterator
/TaminoPageIterator
.
It allows the application to fill a dataset with data from Tamino, modify the
dataset and write the changes back to Tamino just by calling the
Update
method of the
TaminoDataAdapter
object.
Since Tamino is a native XML database, the behavior of the
TaminoDataAdapter
differs slightly from the
corresponding behavior of the SQL-oriented data adapters of the .NET Framework.
The behavior of the individual functions is described below in detail in the
following sections:
A TaminoDataAdapter
object can be used to:
define tables and columns in a dataset,
populate a dataset with Tamino XML data,
write a modified dataset back to Tamino.
It is not mandatory to define tables and columns in a dataset before populating it with Tamino data. If no tables and columns are defined, the schema will be inferred from the data when the dataset is populated. One disadvantage of this is that the process of inferring a schema from XML is not deterministic; therefore the result (i.e., the schema) relies heavily on the specific data from which the schema is inferred. For more information about inference limitations, see Microsoft's .NET documentation (ms-help://MS.NETFrameworkSDK/cpguidenf/html/cpconinferringdatasetrelationalstructurefromxml.htm).
The same TaminoDataAdapter
object can be used to
fill and update multiple datasets. A TaminoDataAdapter
object is always tied to a specific TaminoConnection
object and can only handle data belonging to one Tamino collection.
Updates must be done by the same
TaminoDataAdapter
object that populated the dataset.
This is because the table/column-oriented DataSet
object
does not hold all information about native XML data, and therefore the
TaminoDataAdapter
object has to keep additional
information for subsequent updates.
TaminoDataAdapter
Objects
Collection and connection properties must be specified when creating a
TaminoDataAdapter
object.
An application that wants to leave the handling of connections and
transactions to the TaminoDataAdapter
object should just
specify the database URL and the collection name as strings. The
TaminoDataAdapter
object will then create and use its
own
TaminoConnection
/TaminoCommand
object internally and handle the opening and closing of connections as well as
transactions without any intervention from the application.
An application that prefers to customize transactional settings during
command execution, or control connections and transactions on its own, can pass
TaminoConnection
or TaminoCommand
objects in the constructor. The TaminoDataAdapter
will
then use the passed objects for command execution.
... TaminoDataAdapter adapter = new TaminoDataAdapter("http://myserver/tamino/mydb", "mycollection"); ...
... TaminoConnection connection = new TaminoConnection("http://myserver/tamino/mydb"); TaminoDataAdapter adapter = new TaminoDataAdapter(connection, "mycollection"); ...
... TaminoConnection connection = new TaminoConnection("http://myserver/tamino/mydb"); TaminoCommand command = connection.CreateCommand("mycollection"); TaminoDataAdapter adapter = new TaminoDataAdapter(command); ...
Datasets are designed for disconnected (offline) working. To support
this, the FillSchema
, Fill
and Update
methods of the
TaminoDataAdapter
class handle opening and closing of
the associated connection objects according to the following rules:
If the connection is closed, it is opened by the
TaminoDataAdapter
object and closed again before the
method call returns.
If the connection is open, it remains open when the method call returns.
Similar rules apply to the transaction handling. However, the rules for
transaction handling also depend on whether Fill
or
Update
is executed and on whether filling is done for
read-only or update mode.
TaminoDataAdapter
Behavior
The same methods of the TaminoDataAdapter
object
can be used to fill a dataset for update or readonly mode. However, filling for
readonly is faster, uses fewer resources and poses fewer limitations on the
data with which the dataset can be filled. You should therefore decide whether
your application needs to modify the data or not before the dataset is filled
and set the Behavior
property of the
TaminoDataAdapter
object accordingly.
A DataSet
object that has been filled for
readonly can subsequently be filled for update. However, once a
DataSet
object has been filled for update, it cannot be
filled for readonly. You should therefore fill a DataSet
object either always for readonly or always for update.
... DataSet ds = new DataSet(); adapter.Behavior = TaminoAdapterBehavior.ReadOnly; adapter.Fill(ds); ...
TaminoDataAdapter
and
Synchronized XmlDataDocuments
.NET supports the synchronization of an XmlDataDocument object with a
corresponding DataSet
object. The same
DataSet
object may only be synchronized with exactly one
XmlDataDocument object. The TaminoDataAdapter
class uses
synchronized XmlDataDocuments when filling datasets for later updates. An
application can use the TaminoDataAdapter
object's
GetTaminoResponse
method to access the specific
XmlDataDocument that is synchronized with the dataset. An application must not
synchronize another XmlDataDocument object with a
DataSet
object that has been filled or should be filled
for update by a TaminoDataAdapter
object.
... DataSet ds = new DataSet(); adapter.Behavior = TaminoAdapterBehavior.UpdateByItemMapping; adapter.Fill(ds); XmlDataDocument xdoc = adapter.GetTaminoResponse(ds); ...
Especially when working with data in update mode, an application should
call the TaminoDataAdapter
object's
Dispose
method when it has finished using the dataset
together with the TaminoDataAdapter
object.
... DataSet ds = new DataSet(); ... adapter.Dispose(ds); // release resources for this DataSet ...
... adapter.Dispose(); // release resources for all DataSets handled // by the adapter ...
An application can use the FillSchema
methods
to define tables and columns in the dataset. Depending on the data with which
the dataset should be populated, the application can use different parameters
to specify the dataset schema. To populate the dataset with complete root
elements of Tamino documents, the application can specify the name of the
corresponding schema in Tamino. To populate the dataset with subtrees of XML
documents, the application can specify an XmlReader
object to read the corresponding schema.
... XmlTextReader reader = new XmlTextReader("c:\\tests\\myschema.xsd"); adapter.FillSchema(ds, reader); ...
... adapter.FillSchema(ds, "Property"); // schema name within Tamino ...
For a complete code sample, see the FillSchema example in the DataSetSamples.
There is an overloaded method of the
FillSchema
method which takes an additional parameter.
This method is important if you plan to do updates and these updates imply the
addition of new XML elements. If you modify the XmlDataDocument directly using
the DOM API, insertion should work fine and you should not use this overloaded
method.
If you work with the DataSet
object directly,
the DataSet
object will not maintain the correct
sequence of inserted child elements in relation to the parent. Please note that
not only inserting new rows, but also modifying a row can imply the insertion
of a new XML element. This is the case if the corresponding column has not
previously contained a value. By default, the dataset will insert a new child
at any position within the parent XML element. This position may not be the
same as the position defined in the corresponding Tamino document type, and a
subsequent call to the Update method would fail.
The application can use the overloaded
FillSchema
method to tell the
TaminoDataAdapter
object to use the specified schema for
validation when new elements are inserted. The
TaminoDataAdapter
will then try to correct the element
sequence according to the schema.
... DataSet ds = new DataSet(); adapter.Behavior = TaminoAdapterBehavior.UpdateByItemMapping; adapter.FillSchema(ds, "Property", true); ...
Correction capabilities are limited in the current version of the
Tamino API for .NET. The parent element in which the
sequence of the child elements should be corrected must be a global XML element
in the sense of the XML Schema recommendation (see
http://www.w3.org/TR/xmlschema-0/).
The TaminoDataAdapter
cannot correct the element
ordering for inserts resulting from calls to the
DataSet.RejectChanges()
method. This means: If you
delete complete rows and call RejectChanges()
, then
the correct ordering is not guaranteed. You can avoid this problem by using
TaminoDataAdapter.Fill
instead of
DataSet.RejectChanges()
to undo changes in the
dataset.
The status of the correction implementation is "experimental", meaning
that the TaminoDataAdapter
may not be able to correct
the sequence if the schema is very complex.
The Fill
methods can be used to populate a
dataset with Tamino data. To populate a dataset for read-only, the
Behavior
property of the
TaminoDataAdapter
must be set to
"TaminoAdapterBehavior.ReadOnly" before calling the
Fill
methods.
The XQuery that is used to populate the dataset can either be set via
the Query
property of the
TaminoDataAdapter
class, or it can be passed as a
parameter to the Fill
method. The
Query
property contains the
TaminoQuery
object that was used for the most recently
called Fill
method.
... DataSet ds = new DataSet(); adapter.Behavior = TaminoAdapterBehavior.ReadOnly; adapter.Query = new TaminoQuery("input()/Property/Address"); adapter.Fill(ds); ... adapter.Fill(ds); // (re)filling several times using the same query ...
... DataSet ds = new DataSet(); adapter.Behavior = TaminoAdapterBehavior.ReadOnly; adapter.Fill (ds, new TaminoQuery("input()/Property/Address")); ...
See also the FillReadOnly example in the DataSetSamples.
Note:
When the Fill
method is called, all rows of
all tables in the dataset are cleared.
If the dataset contains tables before the Fill
method is called, then XmlReadMode.IgnoreSchema
is
used for filling. If the dataset does not contain any tables, then
XmlReadMode.InferSchema
is used for filling.
If the TaminoConnection
object associated with
the TaminoDataAdapter
is not open, the connection is
opened in "TaminoConnectionMode.AutoCommit" and it
is closed before the Fill
method returns.
The Fill
methods can be used to populate a
dataset with Tamino data. To populate a dataset for update, the
Behavior
property of the
TaminoDataAdapter
must be set to
"TaminoAdapterBehavior.UpdateByItemMapping" before
calling the Fill
methods. If
"TaminoAdapterBehavior.UpdateByItemMapping" has not
been set before filling, the TaminoDataAdapter
object
will not create nor keep the necessary information for subsequently updating
the data in Tamino. Calling the Update
method later
with the dataset will throw a TaminoException
.
The TaminoQuery
object that is used to populate
a dataset is created using the BuildXQuery
method in
the TaminoXQueryBuilder
class. This extends the passed
XQuery expression to enrich the returned Tamino data with identifying
information for subsequent updates.
... DataSet ds = new DataSet(); adapter.Behavior = TaminoAdapterBehavior.UpdateByItemMapping; TaminoQuery query = TaminoXQueryBuilder.BuildXQuery(null, "input()/Property/Address", TaminoAdapterBehavior.UpdateByItemMapping); adapter.Fill(ds, query); ...
See also the XmlUpdate and RowUpdate examples in the DataSetSamples.
Note:
When the Fill
method is called, all rows of
all tables in the dataset are cleared.
Similarly as when filling for readonly,
XmlReadMode.IgnoreSchema
is used for filling if the
dataset already contains tables and
XmlReadMode.InferSchema
is used if it does not. An
additional restriction applies to filling for update: the schema of the dataset
must reflect the hierarchical structure of the complete XML subtree that is
returned from Tamino. Let us assume that the query returns Sample subtrees like
the following:
<Sample> <Description>filling for update sample</Description> <Person> <Phone>999999999</Phone> <Name> <Fírst>FirstName</First> <Last>LastName</Last> </Name> <Email>myemail@mycompany.com</Email> </Person> </Sample>
The Fill
method will, for instance, throw a
TaminoException
if the dataset does not contain a
corresponding table for the Person
element and
therefore does not maintain the following nested relations: Sample_Person,
Person_Name. You usually can avoid such problems by applying an appropriate
schema to the dataset.
There is one special case that can occur even with schemas: If the root element of your single query items does not contain any attributes and only contains children which themselves have children, like <AttributeLessRoot> below, .NET will not create a table for <AttributeLessRoot>; instead it will apply the name "AttributeLessRoot" to the whole dataset.
<AttributeLessRoot> <ChildWithChildren> <Child1>Child1</Child1> <Child2>Child2</Child2> </ChildWithChildren> </AttributeLessRoot>
The Tamino API for .NET will throw a
TaminoException
when the dataset is filled for update.
You can easily avoid this problem: note that the <AttributeLessRoot>
itself does not contain any useful information that you might want to modify
from within your clients. Instead of querying for <AttributeLessRoot>
elements, query for <ChildWithChildren>.
Filling a dataset for update requires the connection to be opened in "TaminoConnectionMode.LocalTransaction". If the connection is already open in "TaminoConnectionMode.AutoCommit", an exception will be thrown. The query is always executed with lock mode "TaminoLockMode.Shared".
After a dataset has been filled for updates, the application will in general want to modify data. The following describes the most common ways of updating the data in the dataset.
Datasets can easily be bound to Windows Forms or Web Forms controls, for instance the DataGrid control. The control displays the data which is bound to it, and the data can then be modified interactively through the control. See the RowUpdate example of the DataSetSamples for a running example.
Another useful feature of datasets is that they can be used together
with Web services. A Web service scenario with the
TaminoDataAdapter
can be implemented as follows: A
client application might request a filled dataset from a Web service, make some
modifications to the dataset, and send a dataset that just includes the changes
back to the Web service. The Web service might then merge the received changes
into the original dataset and write the changes back to Tamino.
After a dataset has been filled for update by the
TaminoDataAdapter
, an XmlDataDocument is synchronized
with the DataSet
object. Synchronization means that
changes made to either of the two objects are reflected in the other object.
This allows an application to modify the data in the dataset by modifying the
XmlDataDocument using the XML DOM interface. An application can access the
synchronized XmlDataDocument through the
TaminoDataAdapter
class's
GetTaminoResponse
method. See also the XmlUpdate
example of the DataSetSamples.
If you do not make the modifications by modifying the associated XML
document, you might run into problems with the sequence of inserted child
elements. To overcome those problems, you can switch on the validation
capability of the TaminoDataAdapter
object. See
"XmlSchema Validation for inserted XML
Elements".
... XmlDataDocument xdoc = adapter.GetTaminoResponse(ds); ds.EnforceConstraints = false; ... // do modifications via DOM interface ... ds.EnforceConstraints = true: ...
The TaminoDataAdapter
class's
Update
method allows modifications made to the dataset
to be written back to the Tamino database. When the
Update
method is called, the
TaminoDataAdapter
looks for inserted, updated and
deleted items in the dataset. If no modifications are found, the method returns
immediately. If any modifications are found, it creates corresponding XQuery
update expressions for Tamino and executes the updates. An application should
not rely on individual items being updated in a defined sequence.
After successfully updating the data in Tamino, the
TaminoDataAdapter
calls the
AcceptChanges()
method in the
DataSet
object.
Note:
The Update()
method does not implicitly
refill the dataset. If you have used the Update()
method to update your modified items in the database and you want to modify the
same items again, you must call the Fill
method before
making the modifications. Otherwise you will get an error message during the
next update, stating that the items have been modified in the meanwhile.
Datasets are designed to support disconnected (offline) working, in the
sense that reading the data (for filling the dataset) and subsequent updating
are not usually done within the same connection and/or transaction. One impact
of this is that the data may be changed by another application between the Fill
and the Update. To avoid overwriting changes that have already been made by
other applications, the TaminoDataAdapter
refuses to
update a Tamino document if it has been changed in Tamino since the Fill.
Notice that even if the dataset has been filled with subtrees of Tamino
documents, the TaminoDataAdapter
always checks for any
modifications of the whole documents.
If the dataset rows correspond to complete root elements of Tamino
documents and their contents, an application can simply call the
Update
method taking just the
DataSet
object as parameter. The unit of update is
always the complete XML tree starting with the root element.
int count = adapter.Update(ds);
The unit of update is always the complete subtree as returned from
Tamino when the dataset was filled. Within those subtrees all modifications are
allowed: inserting, deleting and updating XML subtrees. However, adding a
complete new subtree to the query result is not supported because the
TaminoDataAdapter
would not know into which Tamino
document and at which point within the document the new subtree should be
inserted.
In contrast to root elements, the application must specify a
TaminoQueryItemMapping
object for each different kind of
subtree in the dataset. These TaminoQueryItemMapping
objects must provide information specifying how to identify uniquely a single
subtree within its parent Tamino XML document.
TaminoQueryItemMapping
s are very similar to unique
constraints in XML schemas (see also:
http://www.w3.org/TR/xmlschema-0/
- specifyingUniqueness). An XPath selector is specified to select a set of
elements within its including XML document. “Fields” are then specified that
must be unique within the scope of the set of selected elements. Notice that
the scope of this uniqueness is only a single document and not a document
set.
The following example shows how to specify
TaminoQueryItemMapping
s.
Assume that the dataset has been filled with <Person> subtrees like the following:
<Person> <Phone>999999999</Phone> <Name> <First>FirstName</First> <Last>LastName</Last> </Name> <Email>myemail@mycompany.com</Email> </Person>
According to .NET's rules for mapping XML to dataset tables and columns, the dataset will contain the following tables:
Phone |
First | Last |
Further assume that the combination of first name and last name
uniquely identifies a single Person subtree within a
TaminoDocument
. Remember that the scope of this
uniqueness is only the document and not the document set.
The application would then specify the following
TaminoQueryItemMapping
for <Person> subtrees:
TaminoQueryItemMapping[] mapping = new TaminoQueryItemMapping[1]; TaminoFieldMapping[] fields = new TaminoFieldMapping[2]; mapping[0] = new TaminoQueryItemMapping ( "Person", // table name ".//Person", // XPath to select Person element sets // within their including Tamino document fields // fields defining uniqueness of Person // elements within the element set. ); fields[0] = new TaminoFieldMapping("Name", "First");// table name, column name fields[1] = new TaminoFieldMapping("Name", "Last"); // table name, column name int count = adapter.Update(ds, mapping);
The Update
method requires the connection to
be opened in
"TaminoConnectionMode.LocalTransaction". If the
connection is already open in
"TaminoConnectionMode.AutoCommit", an exception is
thrown.
If a transaction is not already active when the
Update
method is called, the
TaminoDataAdapter
object starts a new transaction and
either does a commit or a rollback before the Update
method returns. For details of the error handling rules, see “Customizing the Update Behavior”.
An application can customize the Update behavior of the
TaminoDataAdapter
object by setting the following
properties:
In most cases, the Update
method performs
multiple update actions in Tamino, which are all executed within the scope of a
single transaction. In some cases, the application might want to commit the
transaction even though some of the actions have failed. For example, it might
be impossible to update one of the documents because another application has
changed it in the meanwhile; nevertheless, all other changes should be written
back to the Tamino. The behavior is as follows:
Value of ContinueUpdateOnError | Description |
---|---|
False |
This is the default setting. At the first thrown exception, the
processing of update actions is stopped and the If a transaction had already been started before the
If the transaction was started by the
|
True |
The There is one exception to this rule: If SingleItemUpdate (see below) is set to false, the very last step of the update processing is the execution of an update command which contains all collected update actions. If an error occurs in this very last step, an exception is always thrown and the transaction is rolled back. |
The behavior is as follows:
Value of SingleItemUpdates | Description |
---|---|
True | This is the default setting. For each item to be
updated, the TaminoDataAdapter issues a single update
command to Tamino. This setting is useful if the dataset contains only few
and/or very large updated items, and/or the application would like to have
detailed control over individual command execution.
|
False | The TaminoDataAdapter
minimizes the number of round-trips to the Tamino Server. As far as possible,
it combines individual update actions into one big update command. This setting
is useful if the dataset contains many small updated items.
|
The TaminoDataAdapter
exposes two events to
which an application can respond in order to gain detailed control over the
individual update actions that occur when processing the
Update
method. The TaminoUpdating and TaminoUpdated
events are similar to .NET’s RowUpdating and RowUpdated events, see
ms-help://MS.NETFrameworkSDK/cpguidenf/html/cpconaddingremovingadonetproviderevents.htm.
Event | Description |
---|---|
TaminoUpdating | This event signifies that an update operation for a changed item in the dataset is about to begin. The application can respond to this event to do validation checks or modify the item before it is updated, to customize the command that will be used for the update, to skip the updating of single items, to cancel the update, and so on. |
TaminoUpdated | This event signifies that an update operation for a changed item in the dataset has been completed. The application can respond to this event by handling errors that occurred during the update, by deciding whether update processing should continue with the next item or whether it should be cancelled, and so on. |
For a working example of using TaminoDataAdapter
events, see the TaminoUpdatingEvent example in the DataSetSamples.
TaminoUpdatingEventArgs
and
TaminoUpdatedEventArgs
When a TaminoUpdating event is raised, a
TaminoUpdatingEventArgs
object is passed to the event
handlers. When a TaminoUpdated event is raised, a
TaminoUpdatedEventArgs
object is passed accordingly.
The TaminoUpdatingEventArgs
object provides the
following properties:
Property | Description |
---|---|
StatementType |
The type of the update operation: "INSERT", "UPDATE", "DELETE". |
Command |
The TaminoCommand object
to perform the update operation. The application can, for instance, change
transactional properties.
|
QueryExpression |
The XQuery update expression for the update operation. For an "INSERT" operation this is always null. The application can modify this expression. |
Namespaces |
A collection of namespace declarations for the XQuery update expression. For an "INSERT" operation this is always null. The application can modify the namespace declaration. |
Node |
The item as an XML element. The application can use this property to modify the item. |
Row |
The row to which the XML element is mapped within the dataset. The application can use this property to modify the item. |
Status |
Indicates whether an error has occurred. When the event is raised, the value is either "Continue" or "ErrorsOccurred". The application can set the Status to a different value. |
Errors |
The caught exception if status is "ErrorsOccurred". The application can set its own exception. |
The TaminoUpdatedEventArgs
object provides the
following properties:
Property | Description |
---|---|
StatementType |
The type of the update operation: "INSERT", "UPDATE", "DELETE". If SingleUpdateItem is set to false, this property is always set to "UPDATE". |
Command |
The TaminoCommand object
that was used to perform the update operation. An application can, for
instance, reset transactional properties that it had changed during the
TaminoUpdating event.
|
TaminoResponse |
The Tamino response object returned from the update operation. |
Node |
The item as an XML element. If SingleUpdateItem is set to false, this property is always null. |
Row |
The row to which the XML element is mapped within the dataset. If SingleUpdateItem is set to false, this property is always null. |
Status |
Indicates whether an error has occurred. When the event is raised, the value is either "Continue" or "ErrorsOccurred". The application can set the Status to a different value. |
Errors |
The caught exception if status is "ErrorsOccurred". The application can set its own exception. |
The time when the events are raised depends on whether SingleItemUpdates is set to true or false.
If SingleItemUpdate is "true", for each modified item the behavior is as follows:
Create update expression.
Check whether the Tamino document that contains this item has been modified since the dataset was filled.
Raise TaminoUpdating event.
Check Status
property returned from the
event handler and continue or abort update processing.
Issue update command to Tamino.
Raise TaminoUpdated event.
Check Status
property returned from the
event handler and continue with the next item or abort update processing.
If SingleItemUpdate is "false", the behavior is as follows:
For each modified item:
Create update expression.
Raise TaminoUpdating event.
For each item that requires an INSERT operation:
Issue command to Tamino.
Raise TaminoUpdated event.
Check Status
property returned from
the event handler and continue or abort update processing.
For all affected Tamino documents: Check whether they have been changed since the dataset was filled.
Create an update command that combines all update actions for the remaining items.
Issue the update command to Tamino.
Raise TaminoUpdated event.
Since Tamino is a native XML database and the dataset is a
table/column-oriented object, the support provided for datasets by the
TaminoDataAdapter
is limited:
The TaminoDataAdapter
uses the .NET Framework
to map XML to the dataset. This mapping has some restrictions: see the .NET
documentation for limitations.
When using the TaminoDataAdapter
, a single
DataSet
object can only contain the result of one query
at one point in time. The Fill
method always clears
all tables before filling is done. This means that a dataset cannot be filled
from several different Data Sources.
As described in the section "Working with Datasets and the
TaminoDataAdapter
", section "Populating a Dataset for
Update", subsection "Loaded Data and Tables", some restrictions
about the dataset schema apply to filling for updates.
If updating should be a process, the
TaminoDataAdapter
is a stateful object in the sense that
filling and updating must be done by the same
TaminoDataAdapter
object.
As described in the section "Working with Datasets and the
TaminoDataAdapter
", section "Creating and Using
TaminoDataAdapter
Objects", subsection
"TaminoDataAdapter
and Synchronized
XmlDataDocuments", the TaminoDataAdapter
uses
a synchronized XmlDataDocument when filling a dataset for update. This
synchronization has several consequences; for example, the schema of the
dataset cannot be modified after the dataset has been filled. Another
consequence is that once you have filled a single
DataSet
object for update, you cannot fill it again for
readonly.
As described in "XmlSchema
Validation for inserted XML Elements", the sequence of child
elements is not always maintained when updating and inserting new rows by
modifying the DataSet
object directly or using the
DataSet.RejectChanges
method.
When updating complete documents with default namespaces, the
TaminoDataAdapter
adds a namespace prefix to each
element.
Updating subtrees that use default namespaces is not currently supported.