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
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;
26 namespace System.Data {
28 /// an in-memory cache of data
32 [DefaultProperty ("DataSetName")]
34 public class DataSet : MarshalByValueComponent, IListSource,
35 ISupportInitialize, ISerializable {
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;
49 public DataSet() : this ("NewDataSet") {
52 public DataSet(string name) {
54 tableCollection = new DataTableCollection (this);
55 relationCollection = new DataRelationCollection.DataSetRelationCollection (this);
56 properties = new PropertyCollection();
60 protected DataSet(SerializationInfo info, StreamingContext context) : this () {
61 throw new NotImplementedException ();
64 #endregion // Constructors
66 #region Public Properties
68 [DataCategory ("Data")]
69 [DataSysDescription ("Indicates whether comparing strings within the DataSet is case sensitive.")]
70 [DefaultValue (false)]
71 public bool CaseSensitive {
72 get { return caseSensitive; }
74 foreach (DataTable T in Tables) {
75 if (T.VirginCaseSensitive)
76 T.CaseSensitive = value;
79 caseSensitive = value;
83 [DataCategory ("Data")]
84 [DataSysDescription ("The name of this DataSet.")]
86 public string DataSetName {
87 get { return dataSetName; }
88 set { dataSetName = value; }
91 [DataSysDescription ("Indicates a custom \"view\" of the data contained by the DataSet. This view allows filtering, searching, and navigating through the custom data view.")]
93 public DataViewManager DefaultViewManager {
95 if (defaultView == null)
96 defaultView = new DataViewManager (this);
101 [DataSysDescription ("Indicates whether constraint rules are to be followed.")]
102 [DefaultValue (true)]
103 public bool EnforceConstraints {
104 get { return enforceConstraints; }
105 set { enforceConstraints = value; }
109 [DataCategory ("Data")]
110 [DataSysDescription ("The collection that holds custom user information.")]
111 public PropertyCollection ExtendedProperties {
112 get { return properties; }
116 [DataSysDescription ("Indicates that the DataSet has errors.")]
117 public bool HasErrors {
120 throw new NotImplementedException ();
124 [DataCategory ("Data")]
125 [DataSysDescription ("Indicates a locale under which to compare strings within the DataSet.")]
126 public CultureInfo Locale {
131 if (locale == null || !locale.Equals(value)) {
132 // TODO: check if the new locale is valid
133 // TODO: update locale of all tables
139 public void Merge (DataRow[] rows)
141 Merge (rows, false, MissingSchemaAction.Add);
144 public void Merge (DataSet dataSet)
146 Merge (dataSet, false, MissingSchemaAction.Add);
149 public void Merge (DataTable table)
151 Merge (table, false, MissingSchemaAction.Add);
154 public void Merge (DataSet dataSet, bool preserveChanges)
156 Merge (dataSet, preserveChanges, MissingSchemaAction.Add);
160 public void Merge (DataRow[] rows, bool preserveChanges, MissingSchemaAction missingSchemaAction)
162 throw new NotImplementedException();
166 public void Merge (DataSet dataSet, bool preserveChanges, MissingSchemaAction missingSchemaAction)
168 throw new NotImplementedException();
172 public void Merge (DataTable table, bool preserveChanges, MissingSchemaAction missingSchemaAction)
174 throw new NotImplementedException();
177 [DataCategory ("Data")]
178 [DataSysDescription ("Indicates the XML uri namespace for the root element pointed at by this DataSet.")]
180 public string Namespace {
182 get { return _namespace; }
185 //TODO - trigger an event if this happens?
190 [DataCategory ("Data")]
191 [DataSysDescription ("Indicates the prefix of the namespace used for this DataSet.")]
193 public string Prefix {
195 get { return prefix; }
198 //TODO - trigger an event if this happens?
203 [DataCategory ("Data")]
204 [DataSysDescription ("The collection that holds the relations for this DatSet.")]
205 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
206 public DataRelationCollection Relations {
208 return relationCollection;
213 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
214 public override ISite Site {
217 throw new NotImplementedException ();
222 throw new NotImplementedException ();
226 [DataCategory ("Data")]
227 [DataSysDescription ("The collection that holds the tables for this DataSet.")]
228 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
229 public DataTableCollection Tables {
230 get { return tableCollection; }
233 #endregion // Public Properties
235 #region Public Methods
238 public void AcceptChanges()
240 foreach (DataTable tempTable in tableCollection)
241 tempTable.AcceptChanges ();
246 // TODO: if currently bound to a XmlDataDocument
247 // throw a NotSupportedException
248 for (int t = 0; t < tableCollection.Count; t++) {
249 tableCollection[t].Clear ();
253 public virtual DataSet Clone()
255 DataSet Copy = new DataSet ();
256 CopyProperties (Copy);
258 foreach (DataTable Table in Tables) {
259 Copy.Tables.Add (Table.Clone ());
265 // Copies both the structure and data for this DataSet.
266 public DataSet Copy()
268 DataSet Copy = new DataSet ();
269 CopyProperties (Copy);
271 // Copy DatSet's tables
272 foreach (DataTable Table in Tables) {
273 Copy.Tables.Add (Table.Copy ());
280 private void CopyProperties (DataSet Copy)
282 Copy.CaseSensitive = CaseSensitive;
283 //Copy.Container = Container
284 Copy.DataSetName = DataSetName;
285 //Copy.DefaultViewManager
287 Copy.EnforceConstraints = EnforceConstraints;
288 //Copy.ExtendedProperties
290 //Copy.Locale = Locale;
291 Copy.Namespace = Namespace;
292 Copy.Prefix = Prefix;
293 //Copy.Relations = Relations;
298 public DataSet GetChanges()
300 throw new NotImplementedException ();
304 public DataSet GetChanges(DataRowState rowStates)
306 throw new NotImplementedException ();
309 public string GetXml()
311 StringWriter Writer = new StringWriter ();
312 WriteXml (Writer, XmlWriteMode.IgnoreSchema);
313 return Writer.ToString ();
316 public string GetXmlSchema()
318 StringWriter Writer = new StringWriter ();
319 WriteXmlSchema (Writer);
320 return Writer.ToString ();
324 public bool HasChanges()
326 throw new NotImplementedException ();
330 public bool HasChanges(DataRowState rowState)
332 throw new NotImplementedException ();
336 public void InferXmlSchema(XmlReader reader, string[] nsArray)
340 public void InferXmlSchema(Stream stream, string[] nsArray)
342 InferXmlSchema (new XmlTextReader(stream), nsArray);
345 public void InferXmlSchema(TextReader reader, string[] nsArray)
347 InferXmlSchema (new XmlTextReader(reader), nsArray);
350 public void InferXmlSchema(string fileName, string[] nsArray)
352 XmlTextReader reader = new XmlTextReader(fileName);
354 InferXmlSchema (reader, nsArray);
360 public virtual void RejectChanges()
362 throw new NotImplementedException ();
365 public virtual void Reset()
367 throw new NotImplementedException ();
370 public void WriteXml(Stream stream)
372 XmlWriter writer = new XmlTextWriter(stream, null );
378 /// Writes the current data for the DataSet to the specified file.
380 /// <param name="filename">Fully qualified filename to write to</param>
381 public void WriteXml(string fileName)
383 XmlWriter writer = new XmlTextWriter(fileName, null );
390 public void WriteXml(TextWriter writer)
392 XmlWriter xwriter = new XmlTextWriter(writer );
397 public void WriteXml(XmlWriter writer)
399 WriteXml( writer, XmlWriteMode.IgnoreSchema );
402 public void WriteXml(Stream stream, XmlWriteMode mode)
404 XmlWriter writer = new XmlTextWriter(stream, null );
406 WriteXml( writer, mode );
409 public void WriteXml(string fileName, XmlWriteMode mode)
411 XmlWriter writer = new XmlTextWriter(fileName, null );
413 WriteXml( writer, mode );
418 public void WriteXml(TextWriter writer, XmlWriteMode mode)
420 XmlWriter xwriter = new XmlTextWriter(writer);
422 WriteXml( xwriter, mode );
425 public void WriteXml(XmlWriter writer, XmlWriteMode mode)
427 if (writer.WriteState == WriteState.Start)
428 writer.WriteStartDocument (true);
430 ((XmlTextWriter)writer).Formatting = Formatting.Indented;
431 WriteStartElement( writer, mode, Namespace, Prefix, DataSetName );
433 if( mode == XmlWriteMode.WriteSchema )
435 DoWriteXmlSchema( writer );
438 //Write out each table in order, providing it is not
439 //part of another table structure via a nested parent relationship
440 foreach( DataTable table in Tables )
442 bool isTopLevel = true;
443 foreach( DataRelation rel in table.ParentRelations )
454 WriteTable( writer, table, mode );
458 writer.WriteEndElement();
461 public void WriteXmlSchema(Stream stream)
463 XmlWriter writer = new XmlTextWriter(stream, null );
465 WriteXmlSchema( writer );
468 public void WriteXmlSchema(string fileName)
470 XmlWriter writer = new XmlTextWriter( fileName, null );
472 WriteXmlSchema( writer );
475 public void WriteXmlSchema(TextWriter writer)
477 XmlWriter xwriter = new XmlTextWriter( writer );
479 WriteXmlSchema( xwriter );
482 public void WriteXmlSchema(XmlWriter writer)
484 ((XmlTextWriter)writer).Formatting = Formatting.Indented;
485 //Create a skeleton doc and then write the schema
486 //proper which is common to the WriteXml method in schema mode
487 writer.WriteStartDocument();
489 DoWriteXmlSchema( writer );
491 writer.WriteEndDocument();
494 public void ReadXmlSchema(Stream stream)
496 XmlReader reader = new XmlTextReader( stream, null );
497 ReadXmlSchema( reader);
500 public void ReadXmlSchema(string str)
502 XmlReader reader = new XmlTextReader( str );
503 ReadXmlSchema( reader );
506 public void ReadXmlSchema(TextReader treader)
508 XmlReader reader = new XmlTextReader( treader );
509 ReadXmlSchema( reader );
512 public void ReadXmlSchema(XmlReader reader)
514 XmlSchemaMapper SchemaMapper = new XmlSchemaMapper (this);
515 SchemaMapper.Read (reader);
518 public XmlReadMode ReadXml (Stream stream)
520 return ReadXml (new XmlTextReader (stream));
523 public XmlReadMode ReadXml (string str)
525 return ReadXml (new XmlTextReader (str));
528 public XmlReadMode ReadXml (TextReader reader)
530 return ReadXml (new XmlTextReader (reader));
533 public XmlReadMode ReadXml (XmlReader r)
535 XmlDataLoader Loader = new XmlDataLoader (this);
536 // FIXME: somekinda exception?
538 return XmlReadMode.Auto; // FIXME
541 * If document is diffgram we will use diffgram
543 if (r.LocalName == "diffgram")
544 return ReadXml (r, XmlReadMode.DiffGram);
547 * If we already have a schema, or the document
548 * contains an in-line schema, sets XmlReadMode to ReadSchema.
551 // FIXME: is this always true: "if we have tables we have to have schema also"
552 if (Tables.Count > 0)
553 return ReadXml (r, XmlReadMode.ReadSchema);
556 * If we dont have a schema yet and document
557 * contains no inline-schema mode is XmlReadMode.InferSchema
560 return ReadXml (r, XmlReadMode.InferSchema);
564 public XmlReadMode ReadXml (Stream stream, XmlReadMode mode)
566 return ReadXml (new XmlTextReader (stream), mode);
569 public XmlReadMode ReadXml (string str, XmlReadMode mode)
571 return ReadXml (new XmlTextReader (str), mode);
574 public XmlReadMode ReadXml (TextReader reader, XmlReadMode mode)
576 return ReadXml (new XmlTextReader (reader), mode);
580 public XmlReadMode ReadXml (XmlReader reader, XmlReadMode mode)
582 XmlReadMode Result = XmlReadMode.Auto;
584 if (mode == XmlReadMode.DiffGram) {
585 XmlDiffLoader DiffLoader = new XmlDiffLoader (this);
586 DiffLoader.Load (reader);
587 Result = XmlReadMode.DiffGram;
590 XmlDataLoader Loader = new XmlDataLoader (this);
591 Result = Loader.LoadData (reader, mode);
597 #endregion // Public Methods
599 #region Public Events
601 [DataCategory ("Action")]
602 [DataSysDescription ("Occurs when it is not possible to merge schemas for two tables with the same name.")]
603 public event MergeFailedEventHandler MergeFailed;
605 #endregion // Public Events
613 #endregion Destructors
615 #region IListSource methods
616 IList IListSource.GetList ()
618 return DefaultViewManager;
621 bool IListSource.ContainsListCollection {
626 #endregion IListSource methods
628 #region ISupportInitialize methods
629 public void BeginInit ()
631 throw new NotImplementedException ();
634 public void EndInit ()
636 throw new NotImplementedException ();
640 #region ISerializable
641 void ISerializable.GetObjectData (SerializationInfo si, StreamingContext sc)
643 throw new NotImplementedException ();
647 #region Protected Methods
648 protected void GetSerializationData(SerializationInfo info, StreamingContext context)
650 string s = info.GetValue ("XmlDiffGram", typeof (String)) as String;
651 if (s != null) ReadXmlSerializable (new XmlTextReader(new StringReader(s)));
655 protected virtual System.Xml.Schema.XmlSchema GetSchemaSerializable()
657 return null; // FIXME
660 protected virtual void ReadXmlSerializable(XmlReader reader)
662 ReadXml(reader, XmlReadMode.DiffGram); // FIXME
665 protected virtual bool ShouldSerializeRelations ()
670 protected virtual bool ShouldSerializeTables ()
676 protected internal virtual void OnPropertyChanging (PropertyChangedEventArgs pcevent)
681 protected virtual void OnRemoveRelation (DataRelation relation)
686 protected virtual void OnRemoveTable (DataTable table)
691 protected internal void RaisePropertyChanging (string name)
696 #region Private Xml Serialisation
698 private string WriteObjectXml( object o ) {
699 switch (Type.GetTypeCode (o.GetType ())) {
700 case TypeCode.Boolean:
701 return XmlConvert.ToString ((Boolean) o);
703 return XmlConvert.ToString ((Byte) o);
705 return XmlConvert.ToString ((Char) o);
706 case TypeCode.DateTime:
707 return XmlConvert.ToString ((DateTime) o);
708 case TypeCode.Decimal:
709 return XmlConvert.ToString ((Decimal) o);
710 case TypeCode.Double:
711 return XmlConvert.ToString ((Double) o);
713 return XmlConvert.ToString ((Int16) o);
715 return XmlConvert.ToString ((Int32) o);
717 return XmlConvert.ToString ((Int64) o);
719 return XmlConvert.ToString ((SByte) o);
720 case TypeCode.Single:
721 return XmlConvert.ToString ((Single) o);
722 case TypeCode.UInt16:
723 return XmlConvert.ToString ((UInt16) o);
724 case TypeCode.UInt32:
725 return XmlConvert.ToString ((UInt32) o);
726 case TypeCode.UInt64:
727 return XmlConvert.ToString ((UInt64) o);
729 if (o is TimeSpan) return XmlConvert.ToString ((TimeSpan) o);
730 if (o is Guid) return XmlConvert.ToString ((Guid) o);
734 private void WriteTable( XmlWriter writer, DataTable table, XmlWriteMode mode )
736 DataRow[] rows = new DataRow [table.Rows.Count];
737 table.Rows.CopyTo (rows, 0);
738 WriteTable (writer, rows, mode);
741 private void WriteTable( XmlWriter writer, DataRow[] rows, XmlWriteMode mode )
743 //The columns can be attributes, hidden, elements, or simple content
744 //There can be 0-1 simple content cols or 0-* elements
745 System.Collections.ArrayList atts;
746 System.Collections.ArrayList elements;
747 DataColumn simple = null;
749 if (rows.Length == 0) return;
750 DataTable table = rows[0].Table;
751 SplitColumns( table, out atts, out elements, out simple );
753 foreach( DataRow row in rows )
755 //sort out the namespacing
756 string nspc = table.Namespace.Length > 0 ? table.Namespace : Namespace;
758 // First check are all the rows null. If they are we just write empty element
759 bool AllNulls = true;
760 foreach (DataColumn dc in table.Columns) {
762 if (row [dc.ColumnName] != DBNull.Value) {
768 // If all of the columns were null, we have to write empty element
770 writer.WriteElementString (table.TableName, "");
774 WriteStartElement( writer, mode, nspc, table.Prefix, table.TableName );
776 foreach( DataColumn col in atts )
778 WriteAttributeString( writer, mode, col.Namespace, col.Prefix, col.ColumnName, row[col].ToString() );
783 writer.WriteString( WriteObjectXml(row[simple]) );
787 foreach( DataColumn col in elements )
789 string colnspc = nspc;
790 object rowObject = row [col];
792 if (rowObject == null || rowObject == DBNull.Value)
795 if( col.Namespace != null )
797 colnspc = col.Namespace;
800 //TODO check if I can get away with write element string
801 WriteStartElement( writer, mode, colnspc, col.Prefix, col.ColumnName );
802 writer.WriteString( WriteObjectXml(rowObject) );
803 writer.WriteEndElement();
807 foreach (DataRelation relation in table.ChildRelations) {
808 if (relation.Nested) {
809 WriteTable (writer, row.GetChildRows(relation), mode);
813 writer.WriteEndElement();
818 private void WriteStartElement( XmlWriter writer, XmlWriteMode mode, string nspc, string prefix, string name )
822 case XmlWriteMode.WriteSchema:
823 if( nspc == null || nspc == "" )
825 writer.WriteStartElement( name );
827 else if( prefix != null )
829 writer.WriteStartElement(prefix, name, nspc );
833 writer.WriteStartElement( writer.LookupPrefix( nspc ), name, nspc );
836 case XmlWriteMode.DiffGram:
837 throw new NotImplementedException();
839 writer.WriteStartElement(name );
844 private void WriteAttributeString( XmlWriter writer, XmlWriteMode mode, string nspc, string prefix, string name, string stringValue )
848 case XmlWriteMode.WriteSchema:
849 writer.WriteAttributeString(prefix, name, nspc );
851 case XmlWriteMode.DiffGram:
852 throw new NotImplementedException();
854 writer.WriteAttributeString(name, stringValue );
859 private void DoWriteXmlSchema( XmlWriter writer )
861 //Create the root element and declare all the namespaces etc
862 writer.WriteStartElement(XmlConstants.SchemaPrefix, XmlConstants.SchemaElement,
863 XmlConstants.SchemaNamespace );
864 writer.WriteAttributeString( XmlConstants.TargetNamespace, Namespace );
865 writer.WriteAttributeString( "xmlns:" + XmlConstants.TnsPrefix, Namespace );
866 writer.WriteAttributeString( "xmlns", Namespace );
867 writer.WriteAttributeString( "xmlns:" + XmlConstants.MsdataPrefix,
868 XmlConstants.MsdataNamespace );
869 //Set up the attribute and element forms.
870 //TODO - is it possible to change this?
871 //I couldn't spot if it was so I assumed
872 //that this is set to qualified all round basedon the MS output
873 writer.WriteAttributeString( XmlConstants.AttributeFormDefault,
874 XmlConstants.Qualified );
875 writer.WriteAttributeString( XmlConstants.ElementFormDefault,
876 XmlConstants.Qualified );
879 //<xs:element name="DSName msdata:IsDataSet="true" msdata:Locale="machine-locale">
880 //Create the data set element
881 //All the tables are represented as choice elements in an unlimited series
882 writer.WriteStartElement( XmlConstants.SchemaPrefix,
883 XmlConstants.Element,
884 XmlConstants.SchemaNamespace );
886 writer.WriteAttributeString( XmlConstants.Name, DataSetName );
887 writer.WriteAttributeString( XmlConstants.MsdataPrefix, XmlConstants.IsDataSet, XmlConstants.MsdataNamespace, "true" );
888 //FIXME - sort out the locale string!
890 writer.WriteAttributeString( XmlConstants.MsdataPrefix, XmlConstants.Locale, XmlConstants.MsdataNamespace, Thread.CurrentThread.CurrentCulture.Name);
893 writer.WriteStartElement( XmlConstants.SchemaPrefix,
894 XmlConstants.ComplexType,
895 XmlConstants.SchemaNamespace );
897 //<xs:choice maxOccurs="unbounded">
898 writer.WriteStartElement( XmlConstants.SchemaPrefix,
900 XmlConstants.SchemaNamespace );
902 writer.WriteAttributeString( XmlConstants.MaxOccurs, XmlConstants.Unbounded );
905 //Write out schema for each table in order, providing it is not
906 //part of another table structure via a nested parent relationship
907 foreach( DataTable table in Tables )
909 bool isTopLevel = true;
910 foreach( DataRelation rel in table.ParentRelations )
921 WriteTableSchema( writer, table );
926 writer.WriteEndElement();
928 writer.WriteEndElement();
930 //TODO - now add in the relationships as key and unique constraints etc
933 writer.WriteEndElement();
937 writer.WriteEndElement();
940 private void WriteTableSchema( XmlWriter writer, DataTable table )
946 SplitColumns( table,out atts, out elements, out simple );
948 //<xs:element name="TableName">
949 writer.WriteStartElement( XmlConstants.SchemaPrefix,
950 XmlConstants.Element,
951 XmlConstants.SchemaNamespace );
953 writer.WriteAttributeString( XmlConstants.Name, table.TableName );
956 writer.WriteStartElement( XmlConstants.SchemaPrefix,
957 XmlConstants.ComplexType,
958 XmlConstants.SchemaNamespace );
960 //TODO - what about the simple content?
961 if( elements.Count == 0 )
966 //A sequence of element types or a simple content node
968 writer.WriteStartElement( XmlConstants.SchemaPrefix,
969 XmlConstants.Sequence,
970 XmlConstants.SchemaNamespace );
971 foreach( DataColumn col in elements )
973 //<xs:element name=ColumnName type=MappedType Ordinal=index>
974 writer.WriteStartElement( XmlConstants.SchemaPrefix,
975 XmlConstants.Element,
976 XmlConstants.SchemaNamespace );
978 writer.WriteAttributeString( XmlConstants.Name, col.ColumnName );
980 if (col.ColumnName != col.Caption && col.Caption != string.Empty)
981 writer.WriteAttributeString( XmlConstants.MsdataPrefix, XmlConstants.Caption,
982 XmlConstants.MsdataNamespace, col.Caption);
984 if (col.DefaultValue.ToString () != string.Empty)
985 writer.WriteAttributeString( XmlConstants.Default, col.DefaultValue.ToString ());
987 writer.WriteAttributeString( XmlConstants.Type, MapType( col.DataType ) );
989 if( col.AllowDBNull )
991 writer.WriteAttributeString( XmlConstants.MinOccurs, "0" );
994 //writer.WriteAttributeString( XmlConstants.MsdataPrefix,
995 // XmlConstants.Ordinal,
996 // XmlConstants.MsdataNamespace,
997 // col.Ordinal.ToString() );
999 // Write SimpleType if column have MaxLength
1000 if (col.MaxLength > -1) {
1002 WriteTableSimpleType (writer, col);
1007 writer.WriteEndElement();
1010 writer.WriteEndElement();
1013 //Then a list of attributes
1014 foreach( DataColumn col in atts )
1016 //<xs:attribute name=col.ColumnName form="unqualified" type=MappedType/>
1017 writer.WriteStartElement( XmlConstants.SchemaPrefix,
1018 XmlConstants.Attribute,
1019 XmlConstants.SchemaNamespace );
1021 writer.WriteAttributeString( XmlConstants.Name, col.ColumnName );
1022 writer.WriteAttributeString( XmlConstants.Form, XmlConstants.Unqualified );
1023 writer.WriteAttributeString( XmlConstants.Type, MapType( col.DataType ) );
1025 writer.WriteEndElement();
1029 writer.WriteEndElement();
1032 writer.WriteEndElement();
1035 private void WriteTableSimpleType (XmlWriter writer, DataColumn col)
1038 writer.WriteStartElement( XmlConstants.SchemaPrefix, XmlConstants.SimpleType,
1039 XmlConstants.SchemaNamespace);
1042 writer.WriteStartElement( XmlConstants.SchemaPrefix, XmlConstants.Restriction,
1043 XmlConstants.SchemaNamespace);
1045 writer.WriteAttributeString( XmlConstants.Base, MapType( col.DataType ) );
1048 writer.WriteStartElement( XmlConstants.SchemaPrefix, XmlConstants.MaxLength,
1049 XmlConstants.SchemaNamespace);
1050 writer.WriteAttributeString( XmlConstants.Value, col.MaxLength.ToString ());
1053 writer.WriteEndElement();
1055 writer.WriteEndElement();
1057 writer.WriteEndElement();
1061 /// Helper function to split columns into attributes elements and simple
1064 private void SplitColumns( DataTable table,
1066 out ArrayList elements,
1067 out DataColumn simple)
1069 //The columns can be attributes, hidden, elements, or simple content
1070 //There can be 0-1 simple content cols or 0-* elements
1071 atts = new System.Collections.ArrayList();
1072 elements = new System.Collections.ArrayList();
1075 //Sort out the columns
1076 foreach( DataColumn col in table.Columns )
1078 switch( col.ColumnMapping )
1080 case MappingType.Attribute:
1083 case MappingType.Element:
1084 elements.Add( col );
1086 case MappingType.SimpleContent:
1087 if( simple != null )
1089 throw new System.InvalidOperationException( "There may only be one simple content element" );
1094 //ignore Hidden elements
1101 private string MapType( Type type )
1103 string Result = "xs:string";
1105 // TODO: More types to map?
1107 if (typeof (string) == type)
1108 Result = "xs:string";
1109 else if (typeof (short) == type)
1110 Result = "xs:short";
1111 else if (typeof (int) == type)
1113 else if (typeof (long) == type)
1115 else if (typeof (bool) == type)
1116 Result = "xs:boolean";
1117 else if (typeof (byte) == type)
1118 Result = "xs:unsignedByte";
1119 else if (typeof (char) == type)
1121 else if (typeof (DateTime) == type)
1122 Result = "xs:dateTime";
1123 else if (typeof (decimal) == type)
1124 Result = "xs:decimal";
1125 else if (typeof (double) == type)
1126 Result = "xs:double";
1127 else if (typeof (sbyte) == type)
1128 Result = "xs:sbyte";
1129 else if (typeof (Single) == type)
1130 Result = "xs:float";
1131 else if (typeof (TimeSpan) == type)
1132 Result = "xs:duration";
1133 else if (typeof (ushort) == type)
1134 Result = "xs:usignedShort";
1135 else if (typeof (uint) == type)
1136 Result = "xs:unsignedInt";
1137 else if (typeof (ulong) == type)
1138 Result = "xs:unsignedLong";
1143 #endregion //Private Xml Serialisation