public XmlReadMode ReadXml (XmlReader reader)
{
// The documentation from MS for this method is rather
// poor. The following cases have been observed
// during testing:
//
// Reading a table from XML may create a DataSet to
// store child tables.
//
// If the table has at least one column present,
// we do not require the schema to be present in
// the xml. If the table has no columns, neither
// regular data nor diffgrams will be read, but
// will throw an error indicating that schema
// will not be inferred.
//
// We will likely need to take advantage of the
// msdata:MainDataTable attribute added to the
// schema info to load into the appropriate
// locations.
bool isPartOfDataSet = true;
bool isTableNameBlank = false;
XmlReadMode mode = XmlReadMode.ReadSchema;
DataSet dataSet = null;
DataSet ds = new DataSet ();
reader.MoveToContent ();
if (Columns.Count > 0 && reader.LocalName != "diffgram")
mode = ds.ReadXml (reader);
else if (Columns.Count > 0 && reader.LocalName == "diffgram") {
try {
if (TableName == String.Empty)
isTableNameBlank = true;
if (DataSet == null) {
isPartOfDataSet = false;
ds.Tables.Add (this);
mode = ds.ReadXml (reader);
} else
mode = DataSet.ReadXml (reader);
} catch (Exception e) {
if (e.Message == String.Format ("Cannot load diffGram. Table '{0}' is missing in the destination dataset",
reader.LocalName)) {
mode = XmlReadMode.DiffGram;
if (isTableNameBlank)
TableName = String.Empty;
}
} finally {
if (!isPartOfDataSet)
ds.Tables.Remove (this);
}
return mode;
}
else {
mode = ds.ReadXml (reader, XmlReadMode.ReadSchema);
}
if (mode == XmlReadMode.InferSchema)
mode = XmlReadMode.IgnoreSchema;
if (DataSet == null) {
isPartOfDataSet = false;
dataSet = new DataSet ();
if (TableName == String.Empty)
isTableNameBlank = true;
dataSet.Tables.Add (this);
}
DenyXmlResolving (this, ds, mode, isTableNameBlank, isPartOfDataSet);
if (Columns.Count > 0 && TableName != ds.Tables [0].TableName) {
if (isPartOfDataSet == false)
dataSet.Tables.Remove (this);
if (isTableNameBlank && isPartOfDataSet == false)
TableName = String.Empty;
return mode;
}
else {
TableName = ds.Tables [0].TableName;
}
if (!isPartOfDataSet) {
if (Columns.Count > 0) {
dataSet.Merge (ds, true, MissingSchemaAction.Ignore);
} else {
dataSet.Merge (ds, true, MissingSchemaAction.AddWithKey);
}
if (ChildRelations.Count == 0) {
dataSet.Tables.Remove (this);
} else {
dataSet.DataSetName = ds.DataSetName;
}
} else {
if (Columns.Count > 0) {
DataSet.Merge (ds, true, MissingSchemaAction.Ignore);
} else {
DataSet.Merge (ds, true, MissingSchemaAction.AddWithKey);
}
}
return mode;
}
private void DenyXmlResolving (DataTable table, DataSet ds, XmlReadMode mode, bool isTableNameBlank, bool isPartOfDataSet)
{
if (ds.Tables.Count == 0 && table.Columns.Count == 0)
throw new InvalidOperationException ("DataTable does not support schema inference from XML");
if (table.Columns.Count == 0 && ds.Tables [0].TableName != table.TableName && isTableNameBlank == false)
throw new ArgumentException (String.Format ("DataTable '{0}' does not match to any DataTable in source",
table.TableName));
if (table.Columns.Count > 0 && ds.Tables [0].TableName != table.TableName &&
isTableNameBlank == false && mode == XmlReadMode.ReadSchema &&
isPartOfDataSet == false)
throw new ArgumentException (String.Format ("DataTable '{0}' does not match to any DataTable in source",
table.TableName));
if (isPartOfDataSet == true && table.Columns.Count > 0 &&
mode == XmlReadMode.ReadSchema && table.TableName != ds.Tables [0].TableName)
throw new ArgumentException (String.Format ("DataTable '{0}' does not match to any DataTable in source",
table.TableName));
}