2 // System.Data/DataSet.cs
5 // Christopher Podurgiel <cpodurgiel@msn.com>
6 // Daniel Morgan <danmorg@sc.rr.com>
7 // Rodrigo Moya <rodrigo@ximian.com>
8 // Stuart Caborn <stuart.caborn@virgin.net>
9 // Tim Coleman (tim@timcoleman.com)
10 // Ville Palo <vi64pa@koti.soon.fi>
12 // (C) Ximian, Inc. 2002
13 // Copyright (C) Tim Coleman, 2002, 2003
17 using System.Collections;
18 using System.ComponentModel;
19 using System.Globalization;
20 using System.Threading;
22 using System.Runtime.Serialization;
24 using System.Xml.Schema;
25 using System.Xml.Serialization;
26 using System.Data.Common;
28 namespace System.Data {
31 [DefaultProperty ("DataSetName")]
33 public class DataSet : MarshalByValueComponent, IListSource,
34 ISupportInitialize, ISerializable, IXmlSerializable
36 private string dataSetName;
37 private string _namespace = "";
38 private string prefix;
39 private bool caseSensitive;
40 private bool enforceConstraints = true;
41 private DataTableCollection tableCollection;
42 private DataRelationCollection relationCollection;
43 private PropertyCollection properties;
44 private DataViewManager defaultView;
45 private CultureInfo locale = System.Threading.Thread.CurrentThread.CurrentCulture;
49 public DataSet () : this ("NewDataSet")
53 public DataSet (string name)
56 tableCollection = new DataTableCollection (this);
57 relationCollection = new DataRelationCollection.DataSetRelationCollection (this);
58 properties = new PropertyCollection ();
59 this.prefix = String.Empty;
61 this.Locale = CultureInfo.CurrentCulture;
65 protected DataSet (SerializationInfo info, StreamingContext context) : this ()
67 throw new NotImplementedException ();
70 #endregion // Constructors
72 #region Public Properties
74 [DataCategory ("Data")]
75 [DataSysDescription ("Indicates whether comparing strings within the DataSet is case sensitive.")]
76 [DefaultValue (false)]
77 public bool CaseSensitive {
82 foreach (DataTable T in Tables) {
83 if (T.VirginCaseSensitive)
84 T.CaseSensitive = value;
87 caseSensitive = value;
89 foreach (DataTable table in Tables) {
90 foreach (Constraint c in table.Constraints)
91 c.AssertConstraint ();
97 [DataCategory ("Data")]
98 [DataSysDescription ("The name of this DataSet.")]
100 public string DataSetName {
101 get { return dataSetName; }
102 set { dataSetName = value; }
105 [DataSysDescription ("Indicates a custom \"view\" of the data contained by the DataSet. This view allows filtering, searching, and navigating through the custom data view.")]
107 public DataViewManager DefaultViewManager {
109 if (defaultView == null)
110 defaultView = new DataViewManager (this);
115 [DataSysDescription ("Indicates whether constraint rules are to be followed.")]
116 [DefaultValue (true)]
117 public bool EnforceConstraints {
118 get { return enforceConstraints; }
120 if (value != enforceConstraints) {
121 enforceConstraints = value;
123 foreach (DataTable table in Tables) {
124 // first assert all unique constraints
125 foreach (UniqueConstraint uc in table.Constraints.UniqueConstraints)
126 uc.AssertConstraint ();
127 // then assert all foreign keys
128 foreach (ForeignKeyConstraint fk in table.Constraints.ForeignKeyConstraints)
129 fk.AssertConstraint ();
137 [DataCategory ("Data")]
138 [DataSysDescription ("The collection that holds custom user information.")]
139 public PropertyCollection ExtendedProperties {
140 get { return properties; }
144 [DataSysDescription ("Indicates that the DataSet has errors.")]
145 public bool HasErrors {
148 for (int i = 0; i < Tables.Count; i++) {
149 if (Tables[i].HasErrors)
156 [DataCategory ("Data")]
157 [DataSysDescription ("Indicates a locale under which to compare strings within the DataSet.")]
158 public CultureInfo Locale {
163 if (locale == null || !locale.Equals (value)) {
164 // TODO: check if the new locale is valid
165 // TODO: update locale of all tables
171 public void Merge (DataRow[] rows)
173 Merge (rows, false, MissingSchemaAction.Add);
176 public void Merge (DataSet dataSet)
178 Merge (dataSet, false, MissingSchemaAction.Add);
181 public void Merge (DataTable table)
183 Merge (table, false, MissingSchemaAction.Add);
186 public void Merge (DataSet dataSet, bool preserveChanges)
188 Merge (dataSet, preserveChanges, MissingSchemaAction.Add);
192 public void Merge (DataRow[] rows, bool preserveChanges, MissingSchemaAction missingSchemaAction)
195 throw new ArgumentNullException ("rows");
196 if (!IsLegalSchemaAction (missingSchemaAction))
197 throw new ArgumentOutOfRangeException ("missingSchemaAction");
199 MergeManager.Merge (this, rows, preserveChanges, missingSchemaAction);
203 public void Merge (DataSet dataSet, bool preserveChanges, MissingSchemaAction missingSchemaAction)
206 throw new ArgumentNullException ("dataSet");
207 if (!IsLegalSchemaAction (missingSchemaAction))
208 throw new ArgumentOutOfRangeException ("missingSchemaAction");
210 MergeManager.Merge (this, dataSet, preserveChanges, missingSchemaAction);
214 public void Merge (DataTable table, bool preserveChanges, MissingSchemaAction missingSchemaAction)
217 throw new ArgumentNullException ("table");
218 if (!IsLegalSchemaAction (missingSchemaAction))
219 throw new ArgumentOutOfRangeException ("missingSchemaAction");
221 MergeManager.Merge (this, table, preserveChanges, missingSchemaAction);
224 private static bool IsLegalSchemaAction (MissingSchemaAction missingSchemaAction)
226 if (missingSchemaAction == MissingSchemaAction.Add || missingSchemaAction == MissingSchemaAction.AddWithKey
227 || missingSchemaAction == MissingSchemaAction.Error || missingSchemaAction == MissingSchemaAction.Ignore)
232 [DataCategory ("Data")]
233 [DataSysDescription ("Indicates the XML uri namespace for the root element pointed at by this DataSet.")]
235 public string Namespace {
237 get { return _namespace; }
240 //TODO - trigger an event if this happens?
245 [DataCategory ("Data")]
246 [DataSysDescription ("Indicates the prefix of the namespace used for this DataSet.")]
248 public string Prefix {
250 get { return prefix; }
253 //TODO - trigger an event if this happens?
256 value = string.Empty;
258 if (value != this.prefix)
259 RaisePropertyChanging ("Prefix");
264 [DataCategory ("Data")]
265 [DataSysDescription ("The collection that holds the relations for this DatSet.")]
266 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
267 public DataRelationCollection Relations {
269 return relationCollection;
274 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
275 public override ISite Site {
278 throw new NotImplementedException ();
283 throw new NotImplementedException ();
287 [DataCategory ("Data")]
288 [DataSysDescription ("The collection that holds the tables for this DataSet.")]
289 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
290 public DataTableCollection Tables {
291 get { return tableCollection; }
294 #endregion // Public Properties
296 #region Public Methods
299 public void AcceptChanges ()
301 foreach (DataTable tempTable in tableCollection)
302 tempTable.AcceptChanges ();
307 // TODO: if currently bound to a XmlDataDocument
308 // throw a NotSupportedException
309 for (int t = 0; t < tableCollection.Count; t++) {
310 tableCollection[t].Clear ();
314 public virtual DataSet Clone ()
316 DataSet Copy = new DataSet ();
317 CopyProperties (Copy);
319 foreach (DataTable Table in Tables) {
320 Copy.Tables.Add (Table.Clone ());
323 //Copy Relationships between tables after existance of tables
324 //and setting properties correctly
325 CopyRelations (Copy);
330 // Copies both the structure and data for this DataSet.
331 public DataSet Copy ()
333 DataSet Copy = new DataSet ();
334 CopyProperties (Copy);
336 // Copy DatSet's tables
337 foreach (DataTable Table in Tables)
338 Copy.Tables.Add (Table.Copy ());
340 //Copy Relationships between tables after existance of tables
341 //and setting properties correctly
342 CopyRelations (Copy);
348 private void CopyProperties (DataSet Copy)
350 Copy.CaseSensitive = CaseSensitive;
351 //Copy.Container = Container
352 Copy.DataSetName = DataSetName;
353 //Copy.DefaultViewManager
355 Copy.EnforceConstraints = EnforceConstraints;
356 //Copy.ExtendedProperties
358 //Copy.Locale = Locale;
359 Copy.Namespace = Namespace;
360 Copy.Prefix = Prefix;
366 private void CopyRelations (DataSet Copy)
369 //Creation of the relation contains some of the properties, and the constructor
370 //demands these values. instead changing the DataRelation constructor and behaviour the
371 //parameters are pre-configured and sent to the most general constructor
373 foreach (DataRelation MyRelation in this.Relations) {
374 string pTable = MyRelation.ParentTable.TableName;
375 string cTable = MyRelation.ChildTable.TableName;
376 DataColumn[] P_DC = new DataColumn[MyRelation.ParentColumns.Length];
377 DataColumn[] C_DC = new DataColumn[MyRelation.ChildColumns.Length];
380 foreach (DataColumn DC in MyRelation.ParentColumns) {
381 P_DC[i]=Copy.Tables[pTable].Columns[DC.ColumnName];
387 foreach (DataColumn DC in MyRelation.ChildColumns) {
388 C_DC[i]=Copy.Tables[cTable].Columns[DC.ColumnName];
392 DataRelation cRel = new DataRelation (MyRelation.RelationName, P_DC, C_DC);
393 //cRel.ChildColumns = MyRelation.ChildColumns;
394 //cRel.ChildTable = MyRelation.ChildTable;
395 //cRel.ExtendedProperties = cRel.ExtendedProperties;
396 //cRel.Nested = MyRelation.Nested;
397 //cRel.ParentColumns = MyRelation.ParentColumns;
398 //cRel.ParentTable = MyRelation.ParentTable;
400 Copy.Relations.Add (cRel);
407 public DataSet GetChanges ()
409 return GetChanges (DataRowState.Added | DataRowState.Deleted | DataRowState.Modified);
413 public DataSet GetChanges (DataRowState rowStates)
415 if (!HasChanges (rowStates))
418 DataSet copySet = Clone ();
419 Hashtable addedRows = new Hashtable ();
421 IEnumerator tableEnumerator = Tables.GetEnumerator ();
424 while (tableEnumerator.MoveNext ()) {
425 origTable = (DataTable)tableEnumerator.Current;
426 copyTable = copySet.Tables[origTable.TableName];
428 // Look for relations that have this table as child
429 IEnumerator relations = origTable.ParentRelations.GetEnumerator ();
431 IEnumerator rowEnumerator = origTable.Rows.GetEnumerator ();
432 while (rowEnumerator.MoveNext ()) {
433 DataRow row = (DataRow)rowEnumerator.Current;
435 if (row.IsRowChanged (rowStates))
436 AddChangedRow (addedRows, copySet, copyTable, relations, row);
442 void AddChangedRow (Hashtable addedRows, DataSet copySet, DataTable copyTable, IEnumerator relations, DataRow row)
444 if (addedRows.ContainsKey (row)) return;
447 while (relations.MoveNext ()) {
448 DataRow parentRow = row.GetParentRow ((DataRelation) relations.Current);
449 if (parentRow == null || addedRows.ContainsKey (parentRow)) continue;
450 DataTable parentCopyTable = copySet.Tables [parentRow.Table.TableName];
451 AddChangedRow (addedRows, copySet, parentCopyTable, parentRow.Table.ParentRelations.GetEnumerator (), parentRow);
454 DataRow newRow = copyTable.NewRow ();
455 copyTable.Rows.Add (newRow);
456 row.CopyValuesToRow (newRow);
457 newRow.XmlRowID = row.XmlRowID;
458 addedRows.Add (row,row);
463 public DataTableReader GetDataReader (DataTable[] dataTables)
465 throw new NotImplementedException ();
469 public DataTableReader GetDataReader ()
471 throw new NotImplementedException ();
475 public string GetXml ()
477 StringWriter Writer = new StringWriter ();
479 // Sending false for not printing the Processing instruction
480 WriteXml (Writer, XmlWriteMode.IgnoreSchema, false);
481 return Writer.ToString ();
484 public string GetXmlSchema ()
486 StringWriter Writer = new StringWriter ();
487 WriteXmlSchema (Writer);
488 return Writer.ToString ();
492 public bool HasChanges ()
494 return HasChanges (DataRowState.Added | DataRowState.Deleted | DataRowState.Modified);
498 public bool HasChanges (DataRowState rowState)
500 if (((int)rowState & 0xffffffe0) != 0)
501 throw new ArgumentOutOfRangeException ("rowState");
503 DataTableCollection tableCollection = Tables;
505 DataRowCollection rowCollection;
508 for (int i = 0; i < tableCollection.Count; i++) {
509 table = tableCollection[i];
510 rowCollection = table.Rows;
511 for (int j = 0; j < rowCollection.Count; j++) {
512 row = rowCollection[j];
513 if ((row.RowState & rowState) != 0)
522 public void InferXmlSchema (XmlReader reader, string[] nsArray)
526 public void InferXmlSchema (Stream stream, string[] nsArray)
528 InferXmlSchema (new XmlTextReader (stream), nsArray);
531 public void InferXmlSchema (TextReader reader, string[] nsArray)
533 InferXmlSchema (new XmlTextReader (reader), nsArray);
536 public void InferXmlSchema (string fileName, string[] nsArray)
538 XmlTextReader reader = new XmlTextReader (fileName);
540 InferXmlSchema (reader, nsArray);
548 public void Load (IDataReader reader, LoadOption loadOption, DataTable[] tables)
550 throw new NotImplementedException ();
554 public void Load (IDataReader reader, LoadOption loadOption, string[] tables)
556 throw new NotImplementedException ();
560 public virtual void RejectChanges ()
563 bool oldEnforceConstraints = this.EnforceConstraints;
564 this.EnforceConstraints = false;
566 for (i = 0; i < this.Tables.Count;i++)
567 this.Tables[i].RejectChanges ();
569 this.EnforceConstraints = oldEnforceConstraints;
572 public virtual void Reset ()
574 IEnumerator constraintEnumerator;
576 // first we remove all ForeignKeyConstraints (if we will not do that
577 // we will get an exception when clearing the tables).
578 for (int i = 0; i < Tables.Count; i++) {
579 ConstraintCollection cc = Tables[i].Constraints;
580 for (int j = 0; j < cc.Count; j++) {
581 if (cc[j] is ForeignKeyConstraint)
591 public void WriteXml (Stream stream)
593 XmlTextWriter writer = new XmlTextWriter (stream, null);
594 writer.Formatting = Formatting.Indented;
599 /// Writes the current data for the DataSet to the specified file.
601 /// <param name="filename">Fully qualified filename to write to</param>
602 public void WriteXml (string fileName)
604 XmlTextWriter writer = new XmlTextWriter (fileName, null);
605 writer.Formatting = Formatting.Indented;
615 public void WriteXml (TextWriter writer)
617 XmlTextWriter xwriter = new XmlTextWriter (writer);
618 xwriter.Formatting = Formatting.Indented;
622 public void WriteXml (XmlWriter writer)
624 WriteXml (writer, XmlWriteMode.IgnoreSchema, true);
627 public void WriteXml (string filename, XmlWriteMode mode)
629 XmlTextWriter writer = new XmlTextWriter (filename, null);
630 writer.Formatting = Formatting.Indented;
633 WriteXml (writer, mode, true);
640 public void WriteXml (Stream stream, XmlWriteMode mode)
642 XmlTextWriter writer = new XmlTextWriter (stream, null);
643 writer.Formatting = Formatting.Indented;
644 WriteXml (writer, mode, true);
647 public void WriteXml (TextWriter writer, XmlWriteMode mode)
649 XmlTextWriter xwriter = new XmlTextWriter (writer);
650 xwriter.Formatting = Formatting.Indented;
651 WriteXml (xwriter, mode, true);
654 public void WriteXml (XmlWriter writer, XmlWriteMode mode)
656 WriteXml (writer, mode, true);
659 internal void WriteXml (Stream stream, XmlWriteMode mode, bool writePI)
661 XmlTextWriter writer = new XmlTextWriter (stream, null);
662 writer.Formatting = Formatting.Indented;
663 WriteXml (writer, mode, writePI);
666 internal void WriteXml (string fileName, XmlWriteMode mode, bool writePI)
668 XmlTextWriter writer = new XmlTextWriter (fileName, null);
669 writer.Formatting = Formatting.Indented;
672 WriteXml (writer, mode, writePI);
679 internal void WriteXml (TextWriter writer, XmlWriteMode mode, bool writePI)
681 XmlTextWriter xwriter = new XmlTextWriter (writer);
682 xwriter.Formatting = Formatting.Indented;
683 WriteXml (xwriter, mode, writePI);
686 internal void WriteXml (XmlWriter writer, XmlWriteMode mode, bool writePI)
688 if (writePI && (writer.WriteState == WriteState.Start))
689 writer.WriteStartDocument (true);
691 if (mode == XmlWriteMode.DiffGram) {
693 WriteDiffGramElement(writer);
696 WriteStartElement (writer, mode, Namespace, Prefix, XmlConvert.EncodeName (DataSetName));
698 /*********************************************************
699 * This is a patch for interoperability with ms.net. *
700 * Because in web services the .net client expects this *
701 * atrribute even if namespace is an empty string *
702 ********************************************************/
703 if (Namespace == null || Namespace.Length == 0)
704 WriteAttributeString (writer, mode, null, null, "xmlns", Namespace);
706 if (mode == XmlWriteMode.WriteSchema) {
707 DoWriteXmlSchema (writer);
710 WriteTables (writer, mode, Tables, DataRowVersion.Default);
711 if (mode == XmlWriteMode.DiffGram) {
712 writer.WriteEndElement (); //DataSet name
713 if (HasChanges(DataRowState.Modified | DataRowState.Deleted)) {
715 DataSet beforeDS = GetChanges (DataRowState.Modified | DataRowState.Deleted);
716 WriteStartElement (writer, XmlWriteMode.DiffGram, XmlConstants.DiffgrNamespace, XmlConstants.DiffgrPrefix, "before");
717 WriteTables (writer, mode, beforeDS.Tables, DataRowVersion.Original);
718 writer.WriteEndElement ();
721 writer.WriteEndElement (); // DataSet name or diffgr:diffgram
724 public void WriteXmlSchema (Stream stream)
726 XmlTextWriter writer = new XmlTextWriter (stream, null );
727 writer.Formatting = Formatting.Indented;
728 WriteXmlSchema (writer);
731 public void WriteXmlSchema (string fileName)
733 XmlTextWriter writer = new XmlTextWriter (fileName, null);
734 writer.Formatting = Formatting.Indented;
736 WriteXmlSchema (writer);
743 public void WriteXmlSchema (TextWriter writer)
745 XmlTextWriter xwriter = new XmlTextWriter (writer);
746 xwriter.Formatting = Formatting.Indented;
747 WriteXmlSchema (xwriter);
750 public void WriteXmlSchema (XmlWriter writer)
752 //Create a skeleton doc and then write the schema
753 //proper which is common to the WriteXml method in schema mode
754 writer.WriteStartDocument ();
755 DoWriteXmlSchema (writer);
757 writer.WriteEndDocument ();
760 public void ReadXmlSchema (Stream stream)
762 XmlReader reader = new XmlTextReader (stream, null);
763 ReadXmlSchema (reader);
766 public void ReadXmlSchema (string str)
768 XmlReader reader = new XmlTextReader (str);
770 ReadXmlSchema (reader);
777 public void ReadXmlSchema (TextReader treader)
779 XmlReader reader = new XmlTextReader (treader);
780 ReadXmlSchema (reader);
783 public void ReadXmlSchema (XmlReader reader)
785 XmlSchemaMapper SchemaMapper = new XmlSchemaMapper (this);
786 SchemaMapper.Read (reader);
789 public XmlReadMode ReadXml (Stream stream)
791 return ReadXml (new XmlTextReader (stream));
794 public XmlReadMode ReadXml (string str)
796 XmlTextReader reader = new XmlTextReader (str);
798 return ReadXml (reader);
805 public XmlReadMode ReadXml (TextReader reader)
807 return ReadXml (new XmlTextReader (reader));
810 public XmlReadMode ReadXml (XmlReader r)
812 XmlDataLoader Loader = new XmlDataLoader (this);
813 // FIXME: somekinda exception?
815 return XmlReadMode.Auto; // FIXME
817 // Check if the curent element is the process instruction (PI).
818 // if it is move to next element.
819 if (r.LocalName == "xml")
822 // The document can be diffgram if :
823 // 1. The first element is diffgram.
824 if (r.LocalName == "diffgram") {
825 return ReadXml (r, XmlReadMode.DiffGram);
828 bool schemaRead = false;
829 if (r.LocalName == "schema") {
835 // If we read the schema the next element can be a diffgram
836 // that is what happen in web services soap message.
837 if (schemaRead && r.LocalName == "diffgram") {
838 return ReadXml (r, XmlReadMode.DiffGram);
841 // Get the DataSet name.
842 // if this xml is not diffgram then the first element will be the
844 string dataSetName = XmlConvert.DecodeName (r.LocalName);
845 DataSetName = dataSetName;
847 r.ReadStartElement ();
851 // After reading the dataset name there can be three scenarios:
852 // 1. The next part will be the schema of the dataset.
853 // 2. The next part will be the data of the dataset using diffgram.
854 // 3. The next part will be the data of tha dataset without diffgram.
855 // Check if the current element is the schema
856 if (r.LocalName == "schema") {
862 // check if the data was written in a diffgram mode.
863 if (r.LocalName == "diffgram") {
864 return ReadXml (r, XmlReadMode.DiffGram);
867 // If the schema has been read we should read the rest data of the dataset
868 // with ignoreschema mode.
870 ReadXml (r, XmlReadMode.IgnoreSchema, false);
871 return XmlReadMode.ReadSchema;
874 // Read the data of the dataset with inferschema.
875 return ReadXml (r, XmlReadMode.InferSchema, false);
879 public XmlReadMode ReadXml (Stream stream, XmlReadMode mode)
881 return ReadXml (new XmlTextReader (stream), mode);
884 public XmlReadMode ReadXml (string str, XmlReadMode mode)
886 XmlTextReader reader = new XmlTextReader (str);
888 return ReadXml (reader, mode);
895 public XmlReadMode ReadXml (TextReader reader, XmlReadMode mode)
897 return ReadXml (new XmlTextReader (reader), mode);
901 public XmlReadMode ReadXml (XmlReader reader, XmlReadMode mode)
903 // we have to initiate the reader.
904 if (reader.ReadState == ReadState.Initial)
907 // Check if the curent element is the process instruction (PI).
908 // if it is move to next element.
909 if (reader.LocalName == "xml")
910 reader.MoveToContent();
912 XmlReadMode Result = XmlReadMode.Auto;
914 if (mode == XmlReadMode.DiffGram) {
915 if (reader.LocalName != "diffgram"){
916 reader.MoveToContent ();
917 reader.ReadStartElement (); // <DataSet>
919 reader.MoveToContent ();
920 if (reader.LocalName == "schema")
921 ReadXmlSchema (reader);
923 reader.MoveToContent ();
925 XmlDiffLoader DiffLoader = new XmlDiffLoader (this);
926 DiffLoader.Load (reader);
927 Result = XmlReadMode.DiffGram;
930 Result = ReadXml(reader, mode, true);
935 private XmlReadMode ReadXml (XmlReader r, XmlReadMode mode, bool readDataSet) {
938 string dataSetName = XmlConvert.DecodeName (r.LocalName);
939 DataSetName = dataSetName;
940 // get the Namespace of the DataSet.
941 string tmp = r.GetAttribute("xmlns");
945 r.ReadStartElement ();
949 XmlDataLoader Loader = new XmlDataLoader (this);
950 return Loader.LoadData (r, mode);
953 #endregion // Public Methods
955 #region Public Events
957 [DataCategory ("Action")]
958 [DataSysDescription ("Occurs when it is not possible to merge schemas for two tables with the same name.")]
959 public event MergeFailedEventHandler MergeFailed;
961 #endregion // Public Events
969 #endregion Destructors
971 #region IListSource methods
972 IList IListSource.GetList ()
974 return DefaultViewManager;
977 bool IListSource.ContainsListCollection {
982 #endregion IListSource methods
984 #region ISupportInitialize methods
985 public void BeginInit ()
989 public void EndInit ()
994 #region ISerializable
995 void ISerializable.GetObjectData (SerializationInfo si, StreamingContext sc)
997 throw new NotImplementedException ();
1001 #region Protected Methods
1002 protected void GetSerializationData (SerializationInfo info, StreamingContext context)
1004 string s = info.GetValue ("XmlDiffGram", typeof (String)) as String;
1005 if (s != null) ReadXmlSerializable (new XmlTextReader (new StringReader (s)));
1009 protected virtual System.Xml.Schema.XmlSchema GetSchemaSerializable ()
1014 protected virtual void ReadXmlSerializable (XmlReader reader)
1016 ReadXml (reader, XmlReadMode.DiffGram); // FIXME
1019 void IXmlSerializable.ReadXml (XmlReader reader)
1022 ReadXmlSerializable(reader);
1024 // the XmlSerializationReader does this lines!!!
1025 //reader.MoveToContent ();
1026 //reader.ReadEndElement (); // </DataSet>
1029 void IXmlSerializable.WriteXml (XmlWriter writer)
1031 DoWriteXmlSchema (writer);
1032 WriteXml (writer, XmlWriteMode.DiffGram, true);
1035 protected virtual bool ShouldSerializeRelations ()
1040 protected virtual bool ShouldSerializeTables ()
1046 protected internal virtual void OnPropertyChanging (PropertyChangedEventArgs pcevent)
1051 protected virtual void OnRemoveRelation (DataRelation relation)
1056 protected virtual void OnRemoveTable (DataTable table)
1060 protected internal virtual void OnMergeFailed (MergeFailedEventArgs e)
1062 if (MergeFailed != null)
1063 MergeFailed (this, e);
1067 protected internal void RaisePropertyChanging (string name)
1072 #region Private Xml Serialisation
1074 private string WriteObjectXml (object o)
1076 switch (Type.GetTypeCode (o.GetType ())) {
1077 case TypeCode.Boolean:
1078 return XmlConvert.ToString ((Boolean) o);
1080 return XmlConvert.ToString ((Byte) o);
1082 return XmlConvert.ToString ((Char) o);
1083 case TypeCode.DateTime:
1084 return XmlConvert.ToString ((DateTime) o);
1085 case TypeCode.Decimal:
1086 return XmlConvert.ToString ((Decimal) o);
1087 case TypeCode.Double:
1088 return XmlConvert.ToString ((Double) o);
1089 case TypeCode.Int16:
1090 return XmlConvert.ToString ((Int16) o);
1091 case TypeCode.Int32:
1092 return XmlConvert.ToString ((Int32) o);
1093 case TypeCode.Int64:
1094 return XmlConvert.ToString ((Int64) o);
1095 case TypeCode.SByte:
1096 return XmlConvert.ToString ((SByte) o);
1097 case TypeCode.Single:
1098 return XmlConvert.ToString ((Single) o);
1099 case TypeCode.UInt16:
1100 return XmlConvert.ToString ((UInt16) o);
1101 case TypeCode.UInt32:
1102 return XmlConvert.ToString ((UInt32) o);
1103 case TypeCode.UInt64:
1104 return XmlConvert.ToString ((UInt64) o);
1106 if (o is TimeSpan) return XmlConvert.ToString ((TimeSpan) o);
1107 if (o is Guid) return XmlConvert.ToString ((Guid) o);
1108 return o.ToString ();
1111 private void WriteTables (XmlWriter writer, XmlWriteMode mode, DataTableCollection tableCollection, DataRowVersion version)
1113 //Write out each table in order, providing it is not
1114 //part of another table structure via a nested parent relationship
1115 foreach (DataTable table in tableCollection) {
1116 bool isTopLevel = true;
1117 foreach (DataRelation rel in table.ParentRelations) {
1125 WriteTable ( writer, table, mode, version);
1130 private void WriteTable (XmlWriter writer, DataTable table, XmlWriteMode mode, DataRowVersion version)
1132 DataRow[] rows = new DataRow [table.Rows.Count];
1133 table.Rows.CopyTo (rows, 0);
1134 WriteTable (writer, rows, mode, version);
1137 private void WriteTable (XmlWriter writer, DataRow[] rows, XmlWriteMode mode, DataRowVersion version)
1139 //The columns can be attributes, hidden, elements, or simple content
1140 //There can be 0-1 simple content cols or 0-* elements
1141 System.Collections.ArrayList atts;
1142 System.Collections.ArrayList elements;
1143 DataColumn simple = null;
1145 if (rows.Length == 0) return;
1146 DataTable table = rows[0].Table;
1147 SplitColumns (table, out atts, out elements, out simple);
1148 //sort out the namespacing
1149 string nspc = table.Namespace.Length > 0 ? table.Namespace : Namespace;
1151 foreach (DataRow row in rows) {
1152 if (!row.HasVersion(version) ||
1153 (mode == XmlWriteMode.DiffGram && row.RowState == DataRowState.Unchanged
1154 && version == DataRowVersion.Original))
1157 // First check are all the rows null. If they are we just write empty element
1158 bool AllNulls = true;
1159 foreach (DataColumn dc in table.Columns) {
1161 if (row [dc.ColumnName, version] != DBNull.Value) {
1167 // If all of the columns were null, we have to write empty element
1169 writer.WriteElementString (table.TableName, "");
1173 WriteTableElement (writer, mode, table, row, version);
1175 foreach (DataColumn col in atts) {
1176 WriteColumnAsAttribute (writer, mode, col, row, version);
1179 if (simple != null) {
1180 writer.WriteString (WriteObjectXml (row[simple, version]));
1183 foreach (DataColumn col in elements) {
1184 WriteColumnAsElement (writer, mode, nspc, col, row, version);
1188 foreach (DataRelation relation in table.ChildRelations) {
1189 if (relation.Nested) {
1190 WriteTable (writer, row.GetChildRows (relation), mode, version);
1194 writer.WriteEndElement ();
1199 private void WriteColumnAsElement (XmlWriter writer, XmlWriteMode mode, string nspc, DataColumn col, DataRow row, DataRowVersion version)
1201 string colnspc = nspc;
1202 object rowObject = row [col, version];
1204 if (rowObject == null || rowObject == DBNull.Value)
1207 if (col.Namespace != null) {
1208 colnspc = col.Namespace;
1211 //TODO check if I can get away with write element string
1212 WriteStartElement (writer, mode, colnspc, col.Prefix, col.ColumnName);
1213 writer.WriteString (WriteObjectXml (rowObject));
1214 writer.WriteEndElement ();
1217 private void WriteColumnAsAttribute (XmlWriter writer, XmlWriteMode mode, DataColumn col, DataRow row, DataRowVersion version)
1219 WriteAttributeString (writer, mode, col.Namespace, col.Prefix, col.ColumnName, row[col, version].ToString ());
1222 private void WriteTableElement (XmlWriter writer, XmlWriteMode mode, DataTable table, DataRow row, DataRowVersion version)
1224 //sort out the namespacing
1225 string nspc = table.Namespace.Length > 0 ? table.Namespace : Namespace;
1227 WriteStartElement (writer, mode, nspc, table.Prefix, table.TableName);
1229 if (mode == XmlWriteMode.DiffGram) {
1230 WriteAttributeString (writer, mode, XmlConstants.DiffgrNamespace, XmlConstants.DiffgrPrefix, "id", table.TableName + (row.XmlRowID + 1));
1231 WriteAttributeString (writer, mode, XmlConstants.MsdataNamespace, XmlConstants.MsdataPrefix, "rowOrder", row.XmlRowID.ToString());
1232 string modeName = null;
1233 if (row.RowState == DataRowState.Modified)
1234 modeName = "modified";
1235 else if (row.RowState == DataRowState.Added)
1236 modeName = "inserted";
1238 if (version != DataRowVersion.Original && modeName != null)
1239 WriteAttributeString (writer, mode, XmlConstants.DiffgrNamespace, XmlConstants.DiffgrPrefix, "hasChanges", modeName);
1243 private void WriteStartElement (XmlWriter writer, XmlWriteMode mode, string nspc, string prefix, string name)
1245 if (nspc == null || nspc == "") {
1246 writer.WriteStartElement (name);
1248 else if (prefix != null) {
1249 writer.WriteStartElement (prefix, name, nspc);
1252 writer.WriteStartElement (writer.LookupPrefix (nspc), name, nspc);
1256 private void WriteAttributeString (XmlWriter writer, XmlWriteMode mode, string nspc, string prefix, string name, string stringValue)
1259 case XmlWriteMode.WriteSchema:
1260 writer.WriteAttributeString (prefix, name, nspc);
1262 case XmlWriteMode.DiffGram:
1263 writer.WriteAttributeString (prefix, name, nspc,stringValue);
1266 writer.WriteAttributeString (name, stringValue);
1271 internal void WriteIndividualTableContent (XmlWriter writer, DataTable table, XmlWriteMode mode)
1273 ((XmlTextWriter)writer).Formatting = Formatting.Indented;
1275 if (mode == XmlWriteMode.DiffGram) {
1276 SetTableRowsID (table);
1277 WriteDiffGramElement (writer);
1280 WriteStartElement (writer, mode, Namespace, Prefix, XmlConvert.EncodeName (DataSetName));
1282 WriteTable (writer, table, mode, DataRowVersion.Default);
1284 if (mode == XmlWriteMode.DiffGram) {
1285 writer.WriteEndElement (); //DataSet name
1286 if (HasChanges (DataRowState.Modified | DataRowState.Deleted)) {
1288 DataSet beforeDS = GetChanges (DataRowState.Modified | DataRowState.Deleted);
1289 WriteStartElement (writer, XmlWriteMode.DiffGram, XmlConstants.DiffgrNamespace, XmlConstants.DiffgrPrefix, "before");
1290 WriteTable (writer, beforeDS.Tables [table.TableName], mode, DataRowVersion.Original);
1291 writer.WriteEndElement ();
1294 writer.WriteEndElement (); // DataSet name or diffgr:diffgram
1297 XmlSchema IXmlSerializable.GetSchema ()
1299 return BuildSchema ();
1302 XmlSchema BuildSchema ()
1304 return BuildSchema (Tables, Relations);
1307 internal XmlSchema BuildSchema (DataTableCollection tables, DataRelationCollection relations)
1309 string constraintPrefix = "";
1310 XmlSchema schema = new XmlSchema ();
1312 schema.Namespaces.Add("xs", XmlSchema.Namespace);
1313 schema.Namespaces.Add(XmlConstants.MsdataPrefix, XmlConstants.MsdataNamespace);
1315 if (Namespace != "" && Namespace != null) {
1316 schema.AttributeFormDefault = XmlSchemaForm.Qualified;
1317 schema.ElementFormDefault = XmlSchemaForm.Qualified;
1318 schema.TargetNamespace = Namespace;
1319 schema.Namespaces.Add(XmlConstants.TnsPrefix, Namespace);
1320 constraintPrefix = XmlConstants.TnsPrefix + ":";
1323 // set the schema id
1324 schema.Id = DataSetName;
1325 XmlDocument doc = new XmlDocument ();
1326 XmlAttribute xmlnsAttr = doc.CreateAttribute("xmlns");
1327 xmlnsAttr.Value = Namespace;
1329 schema.UnhandledAttributes = new XmlAttribute[] {xmlnsAttr};
1331 XmlSchemaElement elem = new XmlSchemaElement ();
1332 elem.Name = XmlConvert.EncodeName (DataSetName);
1334 XmlAttribute[] atts = new XmlAttribute [2];
1335 atts[0] = doc.CreateAttribute (XmlConstants.MsdataPrefix, XmlConstants.IsDataSet, XmlConstants.MsdataNamespace);
1336 atts[0].Value = "true";
1338 atts[1] = doc.CreateAttribute (XmlConstants.MsdataPrefix, XmlConstants.Locale, XmlConstants.MsdataNamespace);
1339 atts[1].Value = locale.Name;
1340 elem.UnhandledAttributes = atts;
1342 schema.Items.Add (elem);
1344 XmlSchemaComplexType complex = new XmlSchemaComplexType ();
1345 elem.SchemaType = complex;
1347 XmlSchemaChoice choice = new XmlSchemaChoice ();
1348 complex.Particle = choice;
1349 choice.MaxOccursString = XmlConstants.Unbounded;
1351 //Write out schema for each table in order
1352 foreach (DataTable table in tables) {
1353 bool isTopLevel = true;
1354 foreach (DataRelation rel in table.ParentRelations) {
1362 choice.Items.Add (GetTableSchema (doc, table));
1366 AddConstraintsToSchema (elem, constraintPrefix, tables, relations);
1370 // Add all constraints in all tables to the schema.
1371 private void AddConstraintsToSchema (XmlSchemaElement elem, string constraintPrefix, DataTableCollection tables, DataRelationCollection relations)
1373 // first add all unique constraints.
1374 Hashtable uniqueNames = AddUniqueConstraints (elem, constraintPrefix, tables);
1375 // Add all foriegn key constraints.
1376 AddForeignKeys (uniqueNames, elem, constraintPrefix, relations);
1379 // Add unique constaraints to the schema.
1380 // return hashtable with the names of all XmlSchemaUnique elements we created.
1381 private Hashtable AddUniqueConstraints (XmlSchemaElement elem, string constraintPrefix, DataTableCollection tables)
1383 XmlDocument doc = new XmlDocument();
1384 Hashtable uniqueNames = new Hashtable();
1385 foreach (DataTable table in tables) {
1387 foreach (Constraint constaint in table.Constraints) {
1389 if (constaint is UniqueConstraint) {
1390 ArrayList attrs = new ArrayList ();
1391 XmlAttribute attrib;
1392 UniqueConstraint uqConst = (UniqueConstraint)constaint;
1393 XmlSchemaUnique uniq = new XmlSchemaUnique ();
1395 // if column of the constraint is hidden do not write the constraint.
1396 bool isHidden = false;
1397 foreach (DataColumn column in uqConst.Columns) {
1398 if (column.ColumnMapping == MappingType.Hidden) {
1407 // if constaraint name do not exist in the hashtable we can use it.
1408 if (!uniqueNames.ContainsKey (uqConst.ConstraintName)) {
1409 uniq.Name = uqConst.ConstraintName;
1411 // generate new constraint name for the XmlSchemaUnique element.
1413 uniq.Name = uqConst.Table.TableName + "_" + uqConst.ConstraintName;
1414 attrib = doc.CreateAttribute (XmlConstants.MsdataPrefix, XmlConstants.ConstraintName, XmlConstants.MsdataNamespace);
1415 attrib.Value = uqConst.ConstraintName;
1418 if (uqConst.IsPrimaryKey) {
1419 attrib = doc.CreateAttribute (XmlConstants.MsdataPrefix, XmlConstants.PrimaryKey, XmlConstants.MsdataNamespace);
1420 attrib.Value = "true";
1424 uniq.UnhandledAttributes = (XmlAttribute[])attrs.ToArray (typeof (XmlAttribute));
1426 uniq.Selector = new XmlSchemaXPath();
1427 uniq.Selector.XPath = ".//"+constraintPrefix + uqConst.Table.TableName;
1428 XmlSchemaXPath field;
1429 foreach (DataColumn column in uqConst.Columns) {
1430 field = new XmlSchemaXPath();
1431 field.XPath = constraintPrefix+column.ColumnName;
1432 uniq.Fields.Add(field);
1435 elem.Constraints.Add (uniq);
1436 uniqueNames.Add (uniq.Name, null);
1443 // Add the foriegn keys to the schema.
1444 private void AddForeignKeys (Hashtable uniqueNames, XmlSchemaElement elem, string constraintPrefix, DataRelationCollection relations)
1446 if (relations == null) return;
1448 XmlDocument doc = new XmlDocument();
1449 foreach (DataRelation rel in relations) {
1451 if (rel.ParentKeyConstraint == null || rel.ChildKeyConstraint == null)
1454 ArrayList attrs = new ArrayList ();
1455 XmlAttribute attrib;
1456 XmlSchemaKeyref keyRef = new XmlSchemaKeyref();
1457 keyRef.Name = rel.RelationName;
1458 ForeignKeyConstraint fkConst = rel.ChildKeyConstraint;
1459 UniqueConstraint uqConst = rel.ParentKeyConstraint;
1461 string concatName = rel.ParentTable.TableName + "_" + uqConst.ConstraintName;
1462 // first try to find the concatenated name. If we didn't find it - use constraint name.
1463 if (uniqueNames.ContainsKey (concatName)) {
1464 keyRef.Refer = new XmlQualifiedName(concatName);
1467 keyRef.Refer = new XmlQualifiedName(uqConst.ConstraintName);
1471 attrib = doc.CreateAttribute (XmlConstants.MsdataPrefix, XmlConstants.IsNested, XmlConstants.MsdataNamespace);
1472 attrib.Value = "true";
1476 keyRef.Selector = new XmlSchemaXPath();
1477 keyRef.Selector.XPath = ".//" + constraintPrefix + rel.ChildTable.TableName;
1478 XmlSchemaXPath field;
1479 foreach (DataColumn column in rel.ChildColumns) {
1480 field = new XmlSchemaXPath();
1481 field.XPath = constraintPrefix+column.ColumnName;
1482 keyRef.Fields.Add(field);
1484 keyRef.UnhandledAttributes = (XmlAttribute[])attrs.ToArray (typeof (XmlAttribute));
1485 elem.Constraints.Add (keyRef);
1489 private XmlSchemaElement GetTableSchema (XmlDocument doc, DataTable table)
1495 SplitColumns (table, out atts, out elements, out simple);
1497 XmlSchemaElement elem = new XmlSchemaElement ();
1498 elem.Name = table.TableName;
1500 XmlSchemaComplexType complex = new XmlSchemaComplexType ();
1501 elem.SchemaType = complex;
1503 //TODO - what about the simple content?
1504 if (simple != null) {
1505 // add simpleContent
1506 XmlSchemaSimpleContent simpleContent = new XmlSchemaSimpleContent();
1507 complex.ContentModel = simpleContent;
1509 // add column name attribute
1510 XmlAttribute[] xlmAttrs = new XmlAttribute [2];
1511 xlmAttrs[0] = doc.CreateAttribute (XmlConstants.MsdataPrefix, XmlConstants.ColumnName, XmlConstants.MsdataNamespace);
1512 xlmAttrs[0].Value = simple.ColumnName;
1514 // add ordinal attribute
1515 xlmAttrs[1] = doc.CreateAttribute (XmlConstants.MsdataPrefix, XmlConstants.Ordinal, XmlConstants.MsdataNamespace);
1516 xlmAttrs[1].Value = simple.Ordinal.ToString();
1517 simpleContent.UnhandledAttributes = xlmAttrs;
1521 XmlSchemaSimpleContentExtension extension = new XmlSchemaSimpleContentExtension();
1522 simpleContent.Content = extension;
1523 extension.BaseTypeName = MapType (simple.DataType);
1527 //A sequence of element types or a simple content node
1529 XmlSchemaSequence seq = new XmlSchemaSequence ();
1530 complex.Particle = seq;
1532 foreach (DataColumn col in elements) {
1534 // Add element for the column.
1535 XmlSchemaElement colElem = new XmlSchemaElement ();
1536 ArrayList xattrs = new ArrayList();
1538 colElem.Name = col.ColumnName;
1540 if (col.ColumnName != col.Caption && col.Caption != String.Empty) {
1541 xattr = doc.CreateAttribute (XmlConstants.MsdataPrefix, XmlConstants.Caption, XmlConstants.MsdataNamespace);
1542 xattr.Value = col.Caption;
1546 if (col.AutoIncrement == true) {
1547 xattr = doc.CreateAttribute (XmlConstants.MsdataPrefix, XmlConstants.AutoIncrement, XmlConstants.MsdataNamespace);
1548 xattr.Value = "true";
1552 if (col.AutoIncrementSeed != 0) {
1553 xattr = doc.CreateAttribute (XmlConstants.MsdataPrefix, XmlConstants.AutoIncrementSeed, XmlConstants.MsdataNamespace);
1554 xattr.Value = col.AutoIncrementSeed.ToString();
1558 if (col.DefaultValue.ToString () != String.Empty)
1559 colElem.DefaultValue = col.DefaultValue.ToString ();
1561 if (col.MaxLength < 0)
1562 colElem.SchemaTypeName = MapType (col.DataType);
1564 if (colElem.SchemaTypeName == XmlConstants.QnString && col.DataType != typeof (string)
1565 && col.DataType != typeof (char)) {
1566 xattr = doc.CreateAttribute (XmlConstants.MsdataPrefix, XmlConstants.DataType, XmlConstants.MsdataNamespace);
1567 xattr.Value = col.DataType.ToString();
1571 if (col.AllowDBNull) {
1572 colElem.MinOccurs = 0;
1575 //writer.WriteAttributeString (XmlConstants.MsdataPrefix,
1576 // XmlConstants.Ordinal,
1577 // XmlConstants.MsdataNamespace,
1578 // col.Ordinal.ToString ());
1580 // Write SimpleType if column have MaxLength
1581 if (col.MaxLength > -1) {
1582 colElem.SchemaType = GetTableSimpleType (doc, col);
1585 colElem.UnhandledAttributes = (XmlAttribute[])xattrs.ToArray(typeof (XmlAttribute));
1586 seq.Items.Add (colElem);
1589 foreach (DataRelation rel in table.ChildRelations) {
1591 seq.Items.Add(GetTableSchema (doc, rel.ChildTable));
1596 //Then a list of attributes
1597 foreach (DataColumn col in atts) {
1598 //<xs:attribute name=col.ColumnName form="unqualified" type=MappedType/>
1599 XmlSchemaAttribute att = new XmlSchemaAttribute ();
1600 att.Name = col.ColumnName;
1601 att.Form = XmlSchemaForm.Unqualified;
1602 att.SchemaTypeName = MapType (col.DataType);
1603 complex.Attributes.Add (att);
1609 private XmlSchemaSimpleType GetTableSimpleType (XmlDocument doc, DataColumn col)
1612 XmlSchemaSimpleType simple = new XmlSchemaSimpleType ();
1615 XmlSchemaSimpleTypeRestriction restriction = new XmlSchemaSimpleTypeRestriction ();
1616 restriction.BaseTypeName = MapType (col.DataType);
1619 XmlSchemaMaxLengthFacet max = new XmlSchemaMaxLengthFacet ();
1620 max.Value = XmlConvert.ToString (col.MaxLength);
1621 restriction.Facets.Add (max);
1623 simple.Content = restriction;
1627 private void DoWriteXmlSchema (XmlWriter writer)
1629 BuildSchema ().Write (writer);
1633 /// Helper function to split columns into attributes elements and simple
1636 private void SplitColumns (DataTable table,
1638 out ArrayList elements,
1639 out DataColumn simple)
1641 //The columns can be attributes, hidden, elements, or simple content
1642 //There can be 0-1 simple content cols or 0-* elements
1643 atts = new System.Collections.ArrayList ();
1644 elements = new System.Collections.ArrayList ();
1647 //Sort out the columns
1648 foreach (DataColumn col in table.Columns) {
1649 switch (col.ColumnMapping) {
1650 case MappingType.Attribute:
1653 case MappingType.Element:
1656 case MappingType.SimpleContent:
1657 if (simple != null) {
1658 throw new System.InvalidOperationException ("There may only be one simple content element");
1663 //ignore Hidden elements
1669 private void WriteDiffGramElement(XmlWriter writer)
1671 WriteStartElement (writer, XmlWriteMode.DiffGram, XmlConstants.DiffgrNamespace, XmlConstants.DiffgrPrefix, "diffgram");
1672 WriteAttributeString(writer, XmlWriteMode.DiffGram, null, "xmlns", XmlConstants.MsdataPrefix, XmlConstants.MsdataNamespace);
1675 private void SetRowsID()
1677 foreach (DataTable Table in Tables)
1678 SetTableRowsID (Table);
1681 private void SetTableRowsID (DataTable Table)
1684 foreach (DataRow Row in Table.Rows) {
1685 Row.XmlRowID = dataRowID;
1691 private XmlQualifiedName MapType (Type type)
1693 switch (Type.GetTypeCode (type)) {
1694 case TypeCode.String: return XmlConstants.QnString;
1695 case TypeCode.Int16: return XmlConstants.QnShort;
1696 case TypeCode.Int32: return XmlConstants.QnInt;
1697 case TypeCode.Int64: return XmlConstants.QnLong;
1698 case TypeCode.Boolean: return XmlConstants.QnBoolean;
1699 case TypeCode.Byte: return XmlConstants.QnUnsignedByte;
1700 //case TypeCode.Char: return XmlConstants.QnChar;
1701 case TypeCode.DateTime: return XmlConstants.QnDateTime;
1702 case TypeCode.Decimal: return XmlConstants.QnDecimal;
1703 case TypeCode.Double: return XmlConstants.QnDouble;
1704 case TypeCode.SByte: return XmlConstants.QnSbyte;
1705 case TypeCode.Single: return XmlConstants.QnFloat;
1706 case TypeCode.UInt16: return XmlConstants.QnUsignedShort;
1707 case TypeCode.UInt32: return XmlConstants.QnUnsignedInt;
1708 case TypeCode.UInt64: return XmlConstants.QnUnsignedLong;
1711 if (typeof (TimeSpan) == type)
1712 return XmlConstants.QnDuration;
1713 else if (typeof (System.Uri) == type)
1714 return XmlConstants.QnUri;
1715 else if (typeof (byte[]) == type)
1716 return XmlConstants.QnBase64Binary;
1717 else if (typeof (XmlQualifiedName) == type)
1718 return XmlConstants.QnXmlQualifiedName;
1720 return XmlConstants.QnString;
1723 #endregion //Private Xml Serialisation