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 throw new NotImplementedException ();
249 public virtual DataSet Clone()
251 DataSet Copy = new DataSet ();
252 CopyProperties (Copy);
254 foreach (DataTable Table in Tables) {
255 Copy.Tables.Add (Table.Clone ());
261 // Copies both the structure and data for this DataSet.
262 public DataSet Copy()
264 DataSet Copy = new DataSet ();
265 CopyProperties (Copy);
267 // Copy DatSet's tables
268 foreach (DataTable Table in Tables) {
269 Copy.Tables.Add (Table.Copy ());
276 private void CopyProperties (DataSet Copy)
278 Copy.CaseSensitive = CaseSensitive;
279 //Copy.Container = Container
280 Copy.DataSetName = DataSetName;
281 //Copy.DefaultViewManager
283 Copy.EnforceConstraints = EnforceConstraints;
284 //Copy.ExtendedProperties
286 //Copy.Locale = Locale;
287 Copy.Namespace = Namespace;
288 Copy.Prefix = Prefix;
289 //Copy.Relations = Relations;
294 public DataSet GetChanges()
296 throw new NotImplementedException ();
300 public DataSet GetChanges(DataRowState rowStates)
302 throw new NotImplementedException ();
305 public string GetXml()
307 StringWriter Writer = new StringWriter ();
308 WriteXml (Writer, XmlWriteMode.IgnoreSchema);
309 return Writer.ToString ();
312 public string GetXmlSchema()
314 StringWriter Writer = new StringWriter ();
315 WriteXmlSchema (Writer);
316 return Writer.ToString ();
320 public bool HasChanges()
322 throw new NotImplementedException ();
326 public bool HasChanges(DataRowState rowState)
328 throw new NotImplementedException ();
332 public void InferXmlSchema(XmlReader reader, string[] nsArray)
336 public void InferXmlSchema(Stream stream, string[] nsArray)
338 InferXmlSchema (new XmlTextReader(stream), nsArray);
341 public void InferXmlSchema(TextReader reader, string[] nsArray)
343 InferXmlSchema (new XmlTextReader(reader), nsArray);
346 public void InferXmlSchema(string fileName, string[] nsArray)
348 XmlTextReader reader = new XmlTextReader(fileName);
350 InferXmlSchema (reader, nsArray);
356 public virtual void RejectChanges()
358 throw new NotImplementedException ();
361 public virtual void Reset()
363 throw new NotImplementedException ();
366 public void WriteXml(Stream stream)
368 XmlWriter writer = new XmlTextWriter(stream, null );
374 /// Writes the current data for the DataSet to the specified file.
376 /// <param name="filename">Fully qualified filename to write to</param>
377 public void WriteXml(string fileName)
379 XmlWriter writer = new XmlTextWriter(fileName, null );
386 public void WriteXml(TextWriter writer)
388 XmlWriter xwriter = new XmlTextWriter(writer );
393 public void WriteXml(XmlWriter writer)
395 WriteXml( writer, XmlWriteMode.IgnoreSchema );
398 public void WriteXml(Stream stream, XmlWriteMode mode)
400 XmlWriter writer = new XmlTextWriter(stream, null );
402 WriteXml( writer, mode );
405 public void WriteXml(string fileName, XmlWriteMode mode)
407 XmlWriter writer = new XmlTextWriter(fileName, null );
409 WriteXml( writer, mode );
414 public void WriteXml(TextWriter writer, XmlWriteMode mode)
416 XmlWriter xwriter = new XmlTextWriter(writer);
418 WriteXml( xwriter, mode );
421 public void WriteXml(XmlWriter writer, XmlWriteMode mode)
423 ((XmlTextWriter)writer).Formatting = Formatting.Indented;
424 WriteStartElement( writer, mode, Namespace, Prefix, DataSetName );
426 if( mode == XmlWriteMode.WriteSchema )
428 DoWriteXmlSchema( writer );
431 //Write out each table in order, providing it is not
432 //part of another table structure via a nested parent relationship
433 foreach( DataTable table in Tables )
435 bool isTopLevel = true;
436 foreach( DataRelation rel in table.ParentRelations )
447 WriteTable( writer, table, mode );
451 writer.WriteEndElement();
454 public void WriteXmlSchema(Stream stream)
456 XmlWriter writer = new XmlTextWriter(stream, null );
458 WriteXmlSchema( writer );
461 public void WriteXmlSchema(string fileName)
463 XmlWriter writer = new XmlTextWriter( fileName, null );
465 WriteXmlSchema( writer );
468 public void WriteXmlSchema(TextWriter writer)
470 XmlWriter xwriter = new XmlTextWriter( writer );
472 WriteXmlSchema( xwriter );
475 public void WriteXmlSchema(XmlWriter writer)
477 ((XmlTextWriter)writer).Formatting = Formatting.Indented;
478 //Create a skeleton doc and then write the schema
479 //proper which is common to the WriteXml method in schema mode
480 writer.WriteStartDocument();
482 DoWriteXmlSchema( writer );
484 writer.WriteEndDocument();
487 public void ReadXmlSchema(Stream stream)
489 XmlReader reader = new XmlTextReader( stream, null );
490 ReadXmlSchema( reader);
493 public void ReadXmlSchema(string str)
495 XmlReader reader = new XmlTextReader( str );
496 ReadXmlSchema( reader );
499 public void ReadXmlSchema(TextReader treader)
501 XmlReader reader = new XmlTextReader( treader );
502 ReadXmlSchema( reader );
505 public void ReadXmlSchema(XmlReader reader)
507 XmlSchemaMapper SchemaMapper = new XmlSchemaMapper (this);
508 SchemaMapper.Read (reader);
511 public XmlReadMode ReadXml (Stream stream)
513 return ReadXml (new XmlTextReader (stream));
516 public XmlReadMode ReadXml (string str)
518 return ReadXml (new XmlTextReader (str));
521 public XmlReadMode ReadXml (TextReader reader)
523 return ReadXml (new XmlTextReader (reader));
526 public XmlReadMode ReadXml (XmlReader r)
528 XmlDataLoader Loader = new XmlDataLoader (this);
529 // FIXME: somekinda exception?
531 return XmlReadMode.Auto; // FIXME
534 * If document is diffgram we will use diffgram
536 if (r.LocalName == "diffgram")
537 return ReadXml (r, XmlReadMode.DiffGram);
540 * If we already have a schema, or the document
541 * contains an in-line schema, sets XmlReadMode to ReadSchema.
544 // FIXME: is this always true: "if we have tables we have to have schema also"
545 if (Tables.Count > 0)
546 return ReadXml (r, XmlReadMode.ReadSchema);
549 * If we dont have a schema yet and document
550 * contains no inline-schema mode is XmlReadMode.InferSchema
553 return ReadXml (r, XmlReadMode.InferSchema);
557 public XmlReadMode ReadXml (Stream stream, XmlReadMode mode)
559 return ReadXml (new XmlTextReader (stream), mode);
562 public XmlReadMode ReadXml (string str, XmlReadMode mode)
564 return ReadXml (new XmlTextReader (str), mode);
567 public XmlReadMode ReadXml (TextReader reader, XmlReadMode mode)
569 return ReadXml (new XmlTextReader (reader), mode);
573 public XmlReadMode ReadXml (XmlReader reader, XmlReadMode mode)
575 XmlReadMode Result = XmlReadMode.Auto;
577 if (mode == XmlReadMode.DiffGram) {
578 XmlDiffLoader DiffLoader = new XmlDiffLoader (this);
579 DiffLoader.Load (reader);
580 Result = XmlReadMode.DiffGram;
583 XmlDataLoader Loader = new XmlDataLoader (this);
584 Result = Loader.LoadData (reader, mode);
590 #endregion // Public Methods
592 #region Public Events
594 [DataCategory ("Action")]
595 [DataSysDescription ("Occurs when it is not possible to merge schemas for two tables with the same name.")]
596 public event MergeFailedEventHandler MergeFailed;
598 #endregion // Public Events
606 #endregion Destructors
608 #region IListSource methods
609 IList IListSource.GetList ()
611 return DefaultViewManager;
614 bool IListSource.ContainsListCollection {
619 #endregion IListSource methods
621 #region ISupportInitialize methods
622 public void BeginInit ()
624 throw new NotImplementedException ();
627 public void EndInit ()
629 throw new NotImplementedException ();
633 #region ISerializable
634 void ISerializable.GetObjectData (SerializationInfo si, StreamingContext sc)
636 throw new NotImplementedException ();
640 #region Protected Methods
641 protected void GetSerializationData(SerializationInfo info, StreamingContext context)
643 string s = info.GetValue ("XmlDiffGram", typeof (String)) as String;
644 if (s != null) ReadXmlSerializable (new XmlTextReader(new StringReader(s)));
648 protected virtual System.Xml.Schema.XmlSchema GetSchemaSerializable()
650 return null; // FIXME
653 protected virtual void ReadXmlSerializable(XmlReader reader)
655 ReadXml(reader, XmlReadMode.DiffGram); // FIXME
658 protected virtual bool ShouldSerializeRelations ()
663 protected virtual bool ShouldSerializeTables ()
669 protected internal virtual void OnPropertyChanging (PropertyChangedEventArgs pcevent)
674 protected virtual void OnRemoveRelation (DataRelation relation)
679 protected virtual void OnRemoveTable (DataTable table)
684 protected internal void RaisePropertyChanging (string name)
689 #region Private Xml Serialisation
691 private string WriteObjectXml( object o ) {
692 switch (Type.GetTypeCode (o.GetType ())) {
693 case TypeCode.Boolean:
694 return XmlConvert.ToString ((Boolean) o);
696 return XmlConvert.ToString ((Byte) o);
698 return XmlConvert.ToString ((Char) o);
699 case TypeCode.DateTime:
700 return XmlConvert.ToString ((DateTime) o);
701 case TypeCode.Decimal:
702 return XmlConvert.ToString ((Decimal) o);
703 case TypeCode.Double:
704 return XmlConvert.ToString ((Double) o);
706 return XmlConvert.ToString ((Int16) o);
708 return XmlConvert.ToString ((Int32) o);
710 return XmlConvert.ToString ((Int64) o);
712 return XmlConvert.ToString ((SByte) o);
713 case TypeCode.Single:
714 return XmlConvert.ToString ((Single) o);
715 case TypeCode.UInt16:
716 return XmlConvert.ToString ((UInt16) o);
717 case TypeCode.UInt32:
718 return XmlConvert.ToString ((UInt32) o);
719 case TypeCode.UInt64:
720 return XmlConvert.ToString ((UInt64) o);
722 if (o is TimeSpan) return XmlConvert.ToString ((TimeSpan) o);
723 if (o is Guid) return XmlConvert.ToString ((Guid) o);
727 private void WriteTable( XmlWriter writer, DataTable table, XmlWriteMode mode )
729 DataRow[] rows = new DataRow [table.Rows.Count];
730 table.Rows.CopyTo (rows, 0);
731 WriteTable (writer, rows, mode);
734 private void WriteTable( XmlWriter writer, DataRow[] rows, XmlWriteMode mode )
736 //The columns can be attributes, hidden, elements, or simple content
737 //There can be 0-1 simple content cols or 0-* elements
738 System.Collections.ArrayList atts;
739 System.Collections.ArrayList elements;
740 DataColumn simple = null;
742 if (rows.Length == 0) return;
743 DataTable table = rows[0].Table;
744 SplitColumns( table, out atts, out elements, out simple );
746 foreach( DataRow row in rows )
748 //sort out the namespacing
749 string nspc = table.Namespace.Length > 0 ? table.Namespace : Namespace;
751 // First check are all the rows null. If they are we just write empty element
752 bool AllNulls = true;
753 foreach (DataColumn dc in table.Columns) {
755 if (row [dc.ColumnName] != DBNull.Value) {
761 // If all of the columns were null, we have to write empty element
763 writer.WriteElementString (table.TableName, "");
767 WriteStartElement( writer, mode, nspc, table.Prefix, table.TableName );
769 foreach( DataColumn col in atts )
771 WriteAttributeString( writer, mode, col.Namespace, col.Prefix, col.ColumnName, row[col].ToString() );
776 writer.WriteString( WriteObjectXml(row[simple]) );
780 foreach( DataColumn col in elements )
782 string colnspc = nspc;
783 object rowObject = row [col];
785 if (rowObject == null || rowObject == DBNull.Value)
788 if( col.Namespace != null )
790 colnspc = col.Namespace;
793 //TODO check if I can get away with write element string
794 WriteStartElement( writer, mode, colnspc, col.Prefix, col.ColumnName );
795 writer.WriteString( WriteObjectXml(rowObject) );
796 writer.WriteEndElement();
800 foreach (DataRelation relation in table.ChildRelations) {
801 if (relation.Nested) {
802 WriteTable (writer, row.GetChildRows(relation), mode);
806 writer.WriteEndElement();
811 private void WriteStartElement( XmlWriter writer, XmlWriteMode mode, string nspc, string prefix, string name )
815 case XmlWriteMode.WriteSchema:
816 if( nspc == null || nspc == "" )
818 writer.WriteStartElement( name );
820 else if( prefix != null )
822 writer.WriteStartElement(prefix, name, nspc );
826 writer.WriteStartElement( writer.LookupPrefix( nspc ), name, nspc );
829 case XmlWriteMode.DiffGram:
830 throw new NotImplementedException();
832 writer.WriteStartElement(name );
837 private void WriteAttributeString( XmlWriter writer, XmlWriteMode mode, string nspc, string prefix, string name, string stringValue )
841 case XmlWriteMode.WriteSchema:
842 writer.WriteAttributeString(prefix, name, nspc );
844 case XmlWriteMode.DiffGram:
845 throw new NotImplementedException();
847 writer.WriteAttributeString(name, stringValue );
852 private void DoWriteXmlSchema( XmlWriter writer )
854 //Create the root element and declare all the namespaces etc
855 writer.WriteStartElement(XmlConstants.SchemaPrefix, XmlConstants.SchemaElement,
856 XmlConstants.SchemaNamespace );
857 writer.WriteAttributeString( XmlConstants.TargetNamespace, Namespace );
858 writer.WriteAttributeString( "xmlns:" + XmlConstants.TnsPrefix, Namespace );
859 writer.WriteAttributeString( "xmlns", Namespace );
860 writer.WriteAttributeString( "xmlns:" + XmlConstants.MsdataPrefix,
861 XmlConstants.MsdataNamespace );
862 //Set up the attribute and element forms.
863 //TODO - is it possible to change this?
864 //I couldn't spot if it was so I assumed
865 //that this is set to qualified all round basedon the MS output
866 writer.WriteAttributeString( XmlConstants.AttributeFormDefault,
867 XmlConstants.Qualified );
868 writer.WriteAttributeString( XmlConstants.ElementFormDefault,
869 XmlConstants.Qualified );
872 //<xs:element name="DSName msdata:IsDataSet="true" msdata:Locale="machine-locale">
873 //Create the data set element
874 //All the tables are represented as choice elements in an unlimited series
875 writer.WriteStartElement( XmlConstants.SchemaPrefix,
876 XmlConstants.Element,
877 XmlConstants.SchemaNamespace );
879 writer.WriteAttributeString( XmlConstants.Name, DataSetName );
880 writer.WriteAttributeString( XmlConstants.MsdataPrefix, XmlConstants.IsDataSet, XmlConstants.MsdataNamespace, "true" );
881 //FIXME - sort out the locale string!
883 writer.WriteAttributeString( XmlConstants.MsdataPrefix, XmlConstants.Locale, XmlConstants.MsdataNamespace, Thread.CurrentThread.CurrentCulture.Name);
886 writer.WriteStartElement( XmlConstants.SchemaPrefix,
887 XmlConstants.ComplexType,
888 XmlConstants.SchemaNamespace );
890 //<xs:choice maxOccurs="unbounded">
891 writer.WriteStartElement( XmlConstants.SchemaPrefix,
893 XmlConstants.SchemaNamespace );
895 writer.WriteAttributeString( XmlConstants.MaxOccurs, XmlConstants.Unbounded );
898 //Write out schema for each table in order, providing it is not
899 //part of another table structure via a nested parent relationship
900 foreach( DataTable table in Tables )
902 bool isTopLevel = true;
903 foreach( DataRelation rel in table.ParentRelations )
914 WriteTableSchema( writer, table );
919 writer.WriteEndElement();
921 writer.WriteEndElement();
923 //TODO - now add in the relationships as key and unique constraints etc
926 writer.WriteEndElement();
930 writer.WriteEndElement();
933 private void WriteTableSchema( XmlWriter writer, DataTable table )
939 SplitColumns( table,out atts, out elements, out simple );
941 //<xs:element name="TableName">
942 writer.WriteStartElement( XmlConstants.SchemaPrefix,
943 XmlConstants.Element,
944 XmlConstants.SchemaNamespace );
946 writer.WriteAttributeString( XmlConstants.Name, table.TableName );
949 writer.WriteStartElement( XmlConstants.SchemaPrefix,
950 XmlConstants.ComplexType,
951 XmlConstants.SchemaNamespace );
953 //TODO - what about the simple content?
954 if( elements.Count == 0 )
959 //A sequence of element types or a simple content node
961 writer.WriteStartElement( XmlConstants.SchemaPrefix,
962 XmlConstants.Sequence,
963 XmlConstants.SchemaNamespace );
964 foreach( DataColumn col in elements )
966 //<xs:element name=ColumnName type=MappedType Ordinal=index>
967 writer.WriteStartElement( XmlConstants.SchemaPrefix,
968 XmlConstants.Element,
969 XmlConstants.SchemaNamespace );
971 writer.WriteAttributeString( XmlConstants.Name, col.ColumnName );
973 if (col.ColumnName != col.Caption && col.Caption != string.Empty)
974 writer.WriteAttributeString( XmlConstants.MsdataPrefix, XmlConstants.Caption,
975 XmlConstants.MsdataNamespace, col.Caption);
977 if (col.DefaultValue.ToString () != string.Empty)
978 writer.WriteAttributeString( XmlConstants.Default, col.DefaultValue.ToString ());
980 writer.WriteAttributeString( XmlConstants.Type, MapType( col.DataType ) );
982 if( col.AllowDBNull )
984 writer.WriteAttributeString( XmlConstants.MinOccurs, "0" );
987 //writer.WriteAttributeString( XmlConstants.MsdataPrefix,
988 // XmlConstants.Ordinal,
989 // XmlConstants.MsdataNamespace,
990 // col.Ordinal.ToString() );
992 // Write SimpleType if column have MaxLength
993 if (col.MaxLength > -1) {
995 WriteTableSimpleType (writer, col);
1000 writer.WriteEndElement();
1003 writer.WriteEndElement();
1006 //Then a list of attributes
1007 foreach( DataColumn col in atts )
1009 //<xs:attribute name=col.ColumnName form="unqualified" type=MappedType/>
1010 writer.WriteStartElement( XmlConstants.SchemaPrefix,
1011 XmlConstants.Attribute,
1012 XmlConstants.SchemaNamespace );
1014 writer.WriteAttributeString( XmlConstants.Name, col.ColumnName );
1015 writer.WriteAttributeString( XmlConstants.Form, XmlConstants.Unqualified );
1016 writer.WriteAttributeString( XmlConstants.Type, MapType( col.DataType ) );
1018 writer.WriteEndElement();
1022 writer.WriteEndElement();
1025 writer.WriteEndElement();
1028 private void WriteTableSimpleType (XmlWriter writer, DataColumn col)
1031 writer.WriteStartElement( XmlConstants.SchemaPrefix, XmlConstants.SimpleType,
1032 XmlConstants.SchemaNamespace);
1035 writer.WriteStartElement( XmlConstants.SchemaPrefix, XmlConstants.Restriction,
1036 XmlConstants.SchemaNamespace);
1038 writer.WriteAttributeString( XmlConstants.Base, MapType( col.DataType ) );
1041 writer.WriteStartElement( XmlConstants.SchemaPrefix, XmlConstants.MaxLength,
1042 XmlConstants.SchemaNamespace);
1043 writer.WriteAttributeString( XmlConstants.Value, col.MaxLength.ToString ());
1046 writer.WriteEndElement();
1048 writer.WriteEndElement();
1050 writer.WriteEndElement();
1054 /// Helper function to split columns into attributes elements and simple
1057 private void SplitColumns( DataTable table,
1059 out ArrayList elements,
1060 out DataColumn simple)
1062 //The columns can be attributes, hidden, elements, or simple content
1063 //There can be 0-1 simple content cols or 0-* elements
1064 atts = new System.Collections.ArrayList();
1065 elements = new System.Collections.ArrayList();
1068 //Sort out the columns
1069 foreach( DataColumn col in table.Columns )
1071 switch( col.ColumnMapping )
1073 case MappingType.Attribute:
1076 case MappingType.Element:
1077 elements.Add( col );
1079 case MappingType.SimpleContent:
1080 if( simple != null )
1082 throw new System.InvalidOperationException( "There may only be one simple content element" );
1087 //ignore Hidden elements
1094 private string MapType( Type type )
1096 string Result = "xs:string";
1098 // TODO: More types to map?
1100 if (typeof (string) == type)
1101 Result = "xs:string";
1102 else if (typeof (short) == type)
1103 Result = "xs:short";
1104 else if (typeof (int) == type)
1106 else if (typeof (long) == type)
1108 else if (typeof (bool) == type)
1109 Result = "xs:boolean";
1110 else if (typeof (byte) == type)
1111 Result = "xs:unsignedByte";
1112 else if (typeof (char) == type)
1114 else if (typeof (DateTime) == type)
1115 Result = "xs:dateTime";
1116 else if (typeof (decimal) == type)
1117 Result = "xs:decimal";
1118 else if (typeof (double) == type)
1119 Result = "xs:double";
1120 else if (typeof (sbyte) == type)
1121 Result = "xs:sbyte";
1122 else if (typeof (Single) == type)
1123 Result = "xs:float";
1124 else if (typeof (TimeSpan) == type)
1125 Result = "xs:duration";
1126 else if (typeof (ushort) == type)
1127 Result = "xs:usignedShort";
1128 else if (typeof (uint) == type)
1129 Result = "xs:unsignedInt";
1130 else if (typeof (ulong) == type)
1131 Result = "xs:unsignedLong";
1136 #endregion //Private Xml Serialisation