[Mono-list] Patch - First implementation to DataRelation

Alan Tam Tam@SiuLung.com
Tue, 18 Feb 2003 01:47:42 +0800


This is a multi-part message in MIME format.

------=_NextPart_000_001B_01C2D6EF.BA257520
Content-Type: text/plain;
	charset="utf-8"
Content-Transfer-Encoding: 7bit

Proposed ChangeLog:
        * DataRelation.cs: Added storage required to hold the relations.
Checking of constraints are not implemented yet. Extended properties and events
not ready yet.
        * DataRelationCollection.cs: Implemented DataSetRelationCollection and
DataTableRelationCollection, both as inner class of the abstract class
DataRelationCollection (like Microsoft although not documented in ECMA).
        * DataRow.cs: Implemented GetChildRows in a extremely slow way. Need to
implement caching like Microsoft later.
        * DataSet.cs: Uncomment DataRelation related members. Uncomment code
for Nested XML. Implemented WriteTable(XmlWriter, DataRow[], XmlWriteMode) for
use of Nested XML. Fixed a wrong modifier in GetSerializationData.
        * DataTable.cs: Uncomment DataRelation related members.

(btw, DataTableRelationCollection.cs is not even in the build list, so can
safely be removed)

With this patch, a person can:
- Add relations to DataSet and DataTable without error
- Find the relations by DataSet.Relations, DataTable.ChildRelations,
DataTable.ParentRelations
- Find related rows by DataRow.GetChildRows
- Directly use a Typed DataSet generated from MS XSD.exe without any
modification
- Generate Nested XML from a DataSet with DataRelation.Nested set
but not:
- Gurantee constraints are automatically created
- Find the constraints by DataTable.Constraints
- Find related rows by DataRow.GetParentRow, DataRow.GetParentRows
- Enforce unique constraint
- Enforce foreign key constraint

A sample Nested XML generated is like this:
<OEC>
  <OE>
    <OEID>23</OEID>
    <Heading>JUPAS interview</Heading>
    <SubHeading>for form 7 student</SubHeading>
    <OESlot>
      <OEID>23</OEID>
      <OEItemNo>1</OEItemNo>
      <VenueDesc>LG 103</VenueDesc>
    </OESlot>
    <OESlot>
      <OEID>23</OEID>
      <OEItemNo>2</OEItemNo>
      <VenueDesc>LG 103</VenueDesc>
    </OESlot>
  </OE>
  <OE>
    <OEID>24</OEID>
    <Heading>Psychology of Selling</Heading>
    <SubHeading>The Important Things About Selling</SubHeading>
    <OESlot>
      <OEID>24</OEID>
      <OEItemNo>1</OEItemNo>
      <VenueDesc>Broadroom I, Grand Hyatt, Hong Kong
</VenueDesc>
    </OESlot>
  </OE>
</OEC>

Regards,
Alan

------=_NextPart_000_001B_01C2D6EF.BA257520
Content-Type: application/octet-stream;
	name="System.Data.diff"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
	filename="System.Data.diff"

Index: System.Data/DataRelation.cs=0A=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=0A=
RCS file: /mono/mcs/class/System.Data/System.Data/DataRelation.cs,v=0A=
retrieving revision 1.2=0A=
diff -u -r1.2 DataRelation.cs=0A=
--- System.Data/DataRelation.cs	12 Nov 2002 01:41:04 -0000	1.2=0A=
+++ System.Data/DataRelation.cs	17 Feb 2003 17:07:29 -0000=0A=
@@ -3,6 +3,7 @@=0A=
 //=0A=
 // Author:=0A=
 //   Daniel Morgan <danmorg@sc.rr.com>=0A=
+//   Alan Tam Siu Lung <Tam@SiuLung.com>=0A=
 //=0A=
 // (C) 2002 Daniel Morgan=0A=
 // (C) 2002 Ximian, Inc.=0A=
@@ -21,32 +22,53 @@=0A=
 	[DefaultProperty ("RelationName")]=0A=
 	[Serializable]=0A=
 	public class DataRelation {=0A=
+		private DataSet dataSet;=0A=
+		private string relationName;=0A=
+		private UniqueConstraint parentKeyConstraint;=0A=
+		private ForeignKeyConstraint childKeyConstraint;=0A=
+		private DataColumn[] parentColumns;=0A=
+		private DataColumn[] childColumns;=0A=
+		private bool nested;=0A=
+		internal bool createConstraints;=0A=
 =0A=
 		#region Constructors=0A=
 =0A=
-		[MonoTODO]=0A=
 		public DataRelation (string relationName, DataColumn parentColumn, =
DataColumn childColumn) =0A=
+		: this(relationName, parentColumn, childColumn, true)=0A=
 		{=0A=
-			throw new NotImplementedException ();=0A=
 		}=0A=
 =0A=
-		[MonoTODO]=0A=
 		public DataRelation (string relationName, DataColumn[] parentColumns, =
DataColumn[] childColumns) =0A=
+		: this(relationName, parentColumns, childColumns, true)=0A=
 		{=0A=
-=0A=
-			throw new NotImplementedException ();=0A=
 		}=0A=
 =0A=
-		[MonoTODO]=0A=
-		public DataRelation (string relationName, DataColumn parentColumn, =
DataColumn childColumn, bool createConstraints)=0A=
+		public DataRelation (string relationName, DataColumn parentColumn, =
DataColumn childColumn, bool createConstraints)=0A=
+		: this(relationName, new DataColumn[] { parentColumn }, new =
DataColumn[] { childColumn }, createConstraints)=0A=
 		{=0A=
-			throw new NotImplementedException ();=0A=
 		}=0A=
 =0A=
-		[MonoTODO]=0A=
 		public DataRelation (string relationName, DataColumn[] parentColumns, =
DataColumn[] childColumns, bool createConstraints) =0A=
 		{=0A=
-			throw new NotImplementedException ();=0A=
+			if (relationName =3D=3D null) relationName =3D "Relation";=0A=
+			this.relationName =3D relationName;=0A=
+			if (parentColumns =3D=3D null) throw new ArgumentNullException ();=0A=
+			this.parentColumns =3D parentColumns;=0A=
+			if (childColumns =3D=3D null) throw new ArgumentNullException ();=0A=
+			this.childColumns =3D childColumns;=0A=
+			this.createConstraints =3D createConstraints;=0A=
+			if (parentColumns.Length !=3D childColumns.Length)=0A=
+				throw new InvalidConstraintException ();=0A=
+			DataTable parentTable =3D parentColumns[0].Table;=0A=
+			DataTable childTable =3D childColumns[0].Table;=0A=
+			if (parentTable.DataSet !=3D childTable.DataSet)=0A=
+				throw new InvalidConstraintException ();=0A=
+			foreach (DataColumn column in parentColumns)=0A=
+				if (column.Table !=3D parentTable)=0A=
+					throw new InvalidConstraintException ();=0A=
+			foreach (DataColumn column in childColumns)=0A=
+				if (column.Table !=3D childTable)=0A=
+					throw new InvalidConstraintException ();=0A=
 		}=0A=
 =0A=
 		[MonoTODO]=0A=
@@ -63,32 +85,32 @@=0A=
 		[DataCategory ("Data")]=0A=
 		[DataSysDescription ("Indicates the child columns of this relation.")]=0A=
 		public virtual DataColumn[] ChildColumns {=0A=
-			[MonoTODO]=0A=
 			get {=0A=
-				throw new NotImplementedException ();=0A=
+				return childColumns;=0A=
 			}=0A=
 		}=0A=
 =0A=
 		public virtual ForeignKeyConstraint ChildKeyConstraint {=0A=
-			[MonoTODO]=0A=
 			get {=0A=
-				throw new NotImplementedException ();=0A=
+				return childKeyConstraint;=0A=
 			}=0A=
 		}=0A=
 =0A=
+		internal void SetChildKeyConstraint(ForeignKeyConstraint =
foreignKeyConstraint) {=0A=
+			childKeyConstraint =3D foreignKeyConstraint;=0A=
+		}=0A=
+=0A=
 		public virtual DataTable ChildTable {=0A=
-			[MonoTODO]=0A=
 			get {=0A=
-				throw new NotImplementedException ();=0A=
+				return childColumns[0].Table;=0A=
 			}=0A=
 		}=0A=
 =0A=
 		[Browsable (false)]=0A=
 		[DesignerSerializationVisibility =
(DesignerSerializationVisibility.Hidden)]=0A=
 		public virtual DataSet DataSet {=0A=
-			[MonoTODO]=0A=
 			get {=0A=
-				throw new NotImplementedException ();=0A=
+				return childColumns[0].Table.DataSet;=0A=
 			}=0A=
 		}=0A=
 =0A=
@@ -96,7 +118,6 @@=0A=
 		[DataCategory ("Data")]=0A=
 		[DataSysDescription ("The collection that holds custom user =
information.")]=0A=
 		public PropertyCollection ExtendedProperties {=0A=
-			[MonoTODO]=0A=
 			get {=0A=
 				throw new NotImplementedException ();=0A=
 			}=0A=
@@ -106,37 +127,36 @@=0A=
 		[DataSysDescription ("Indicates whether relations are nested.")]=0A=
 		[DefaultValue (false)]=0A=
 		public virtual bool Nested {=0A=
-			[MonoTODO]=0A=
 			get {=0A=
-				throw new NotImplementedException ();=0A=
+				return nested;=0A=
 			} =0A=
 			=0A=
-			[MonoTODO]=0A=
 			set {=0A=
-				throw new NotImplementedException ();=0A=
+				nested =3D value;=0A=
 			}=0A=
 		}=0A=
 =0A=
 		[DataCategory ("Data")]=0A=
 		[DataSysDescription ("Indicates the parent columns of this =
relation.")]=0A=
 		public virtual DataColumn[] ParentColumns {=0A=
-			[MonoTODO]=0A=
 			get {=0A=
-				throw new NotImplementedException ();=0A=
+				return parentColumns;=0A=
 			}=0A=
 		}=0A=
 =0A=
 		public virtual UniqueConstraint ParentKeyConstraint {=0A=
-			[MonoTODO]=0A=
 			get {=0A=
-				throw new NotImplementedException ();=0A=
+				return parentKeyConstraint;=0A=
 			}=0A=
 		}=0A=
 =0A=
+		internal void SetParentKeyConstraint(UniqueConstraint =
uniqueConstraint) {=0A=
+			parentKeyConstraint =3D uniqueConstraint;=0A=
+		}=0A=
+=0A=
 		public virtual DataTable ParentTable {=0A=
-			[MonoTODO]=0A=
 			get {=0A=
-				throw new NotImplementedException ();=0A=
+				return parentColumns[0].Table;=0A=
 			}=0A=
 		}=0A=
 =0A=
@@ -144,14 +164,12 @@=0A=
 		[DataSysDescription ("The name used to look up this relation in the =
Relations collection of a DataSet.")]=0A=
 		[DefaultValue ("")]=0A=
 		public virtual string RelationName {=0A=
-			[MonoTODO]=0A=
 			get {=0A=
-				throw new NotImplementedException ();=0A=
+				return relationName;=0A=
 			}=0A=
 			=0A=
-			[MonoTODO]=0A=
 			set {=0A=
-				throw new NotImplementedException ();=0A=
+				relationName =3D value;=0A=
 			}=0A=
 		}=0A=
 =0A=
@@ -159,12 +177,21 @@=0A=
 =0A=
 		#region Methods=0A=
 =0A=
-		[MonoTODO]=0A=
 		protected void CheckStateForProperty () =0A=
 		{=0A=
-			throw new NotImplementedException ();=0A=
+			DataTable parentTable =3D parentColumns[0].Table;=0A=
+			DataTable childTable =3D parentColumns[0].Table;=0A=
+			if (parentTable.DataSet !=3D childTable.DataSet)=0A=
+			throw new DataException ();=0A=
+			bool allColumnsEqual =3D false;=0A=
+			for (int colCnt =3D 0; colCnt < parentColumns.Length; ++colCnt) {=0A=
+				if (!parentColumns [colCnt].DataType.Equals (childColumns =
[colCnt].DataType))=0A=
+					throw new DataException ();=0A=
+				if (parentColumns [colCnt] !=3D childColumns [colCnt]) =
allColumnsEqual =3D false;=0A=
+			}=0A=
+			if (allColumnsEqual) throw new DataException ();=0A=
 		}=0A=
-	=0A=
+=0A=
 		[MonoTODO]=0A=
 		protected internal void OnPropertyChanging (PropertyChangedEventArgs =
pcevent)=0A=
 		{=0A=
@@ -177,10 +204,9 @@=0A=
 			throw new NotImplementedException ();=0A=
 		}=0A=
 =0A=
-		[MonoTODO]=0A=
 		public override string ToString () =0A=
 		{=0A=
-			throw new NotImplementedException ();=0A=
+			return relationName;=0A=
 		}=0A=
 =0A=
 		#endregion // Methods=0A=
Index: System.Data/DataRelationCollection.cs=0A=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=0A=
RCS file: =
/mono/mcs/class/System.Data/System.Data/DataRelationCollection.cs,v=0A=
retrieving revision 1.4=0A=
diff -u -r1.4 DataRelationCollection.cs=0A=
--- System.Data/DataRelationCollection.cs	12 Nov 2002 01:41:04 -0000	1.4=0A=
+++ System.Data/DataRelationCollection.cs	17 Feb 2003 17:07:30 -0000=0A=
@@ -5,6 +5,7 @@=0A=
 //   Christopher Podurgiel (cpodurgiel@msn.com)=0A=
 //   Daniel Morgan <danmorg@sc.rr.com>=0A=
 //   Tim Coleman (tim@timcoleman.com)=0A=
+//   Alan Tam Siu Lung <Tam@SiuLung.com>=0A=
 //=0A=
 // (C) Chris Podurgiel=0A=
 // (C) 2002 Daniel Morgan=0A=
@@ -23,6 +24,135 @@=0A=
 	[Serializable]=0A=
 	public abstract class DataRelationCollection : =
InternalDataCollectionBase=0A=
 	{=0A=
+		/// <summary>=0A=
+		/// Summary description for DataTableRelationCollection.=0A=
+		/// </summary>=0A=
+		internal class DataSetRelationCollection : DataRelationCollection=0A=
+		{=0A=
+			private DataSet dataSet;=0A=
+			=0A=
+			/// <summary>=0A=
+			/// Initializes a new instance of the DataSetRelationCollection =
class.=0A=
+			/// </summary>=0A=
+			internal DataSetRelationCollection (DataSet dataSet)=0A=
+			{=0A=
+				this.dataSet =3D dataSet;=0A=
+			}=0A=
+=0A=
+			/// <summary>=0A=
+			/// Gets the DataRelation object specified by name.=0A=
+			/// </summary>=0A=
+			public override DataRelation this [string name]=0A=
+			{=0A=
+				get {=0A=
+					foreach (DataRelation dataRelation in List)=0A=
+						if (dataRelation.RelationName =3D=3D name) return dataRelation;=0A=
+					return null;=0A=
+				}=0A=
+			}=0A=
+=0A=
+			/// <summary>=0A=
+			/// Gets the DataRelation object at the specified index.=0A=
+			/// </summary>=0A=
+			[MonoTODO]=0A=
+			public override DataRelation this [int index]=0A=
+			{=0A=
+				get {=0A=
+					return List [index] as DataRelation;=0A=
+				}=0A=
+			}=0A=
+=0A=
+			protected override DataSet GetDataSet()=0A=
+			{=0A=
+				return dataSet;=0A=
+			}=0A=
+=0A=
+			/// <summary>=0A=
+			/// Performs verification on the table.=0A=
+			/// </summary>=0A=
+			/// <param name=3D"relation">The relation to check.</param>=0A=
+			[MonoTODO]=0A=
+			protected override void AddCore (DataRelation relation)=0A=
+			{=0A=
+				base.AddCore (relation);=0A=
+				if (relation.ChildTable.DataSet !=3D this.dataSet || =
relation.ParentTable.DataSet !=3D this.dataSet)=0A=
+					throw new DataException ();=0A=
+				List.Add (relation);=0A=
+				relation.ParentTable.ChildRelations.Add (relation);=0A=
+				relation.ChildTable.ParentRelations.Add (relation);=0A=
+				ForeignKeyConstraint foreignKeyConstraint =3D null;=0A=
+				if (relation.createConstraints) {=0A=
+					foreignKeyConstraint =3D new ForeignKeyConstraint =
(relation.ParentColumns, relation.ChildColumns);=0A=
+					relation.ChildTable.Constraints.Add (foreignKeyConstraint);=0A=
+				}=0A=
+				UniqueConstraint uniqueConstraint =3D null;=0A=
+				foreach (object o in List) {=0A=
+					if (o is UniqueConstraint) {=0A=
+						UniqueConstraint uc =3D (UniqueConstraint) o;=0A=
+						if (uc.Columns.Length =3D=3D relation.ParentColumns.Length) {=0A=
+							bool allColumnsEqual =3D true;=0A=
+							for (int columnCnt =3D 0; columnCnt < uc.Columns.Length; =
++columnCnt) {=0A=
+								if (uc.Columns[columnCnt] !=3D =
relation.ParentColumns[columnCnt]) {=0A=
+									allColumnsEqual =3D false;=0A=
+									break;=0A=
+								}=0A=
+							}=0A=
+							if (allColumnsEqual) {=0A=
+								uniqueConstraint =3D uc;=0A=
+								break;=0A=
+							}=0A=
+						}=0A=
+					}=0A=
+				}=0A=
+				relation.SetParentKeyConstraint (uniqueConstraint);=0A=
+				relation.SetChildKeyConstraint (foreignKeyConstraint);=0A=
+			}=0A=
+		}=0A=
+=0A=
+		/// <summary>=0A=
+		/// Summary description for DataTableRelationCollection.=0A=
+		/// </summary>=0A=
+		internal class DataTableRelationCollection : DataRelationCollection=0A=
+		{=0A=
+			private DataTable dataTable;=0A=
+			=0A=
+			/// <summary>=0A=
+			/// Initializes a new instance of the DataTableRelationCollection =
class.=0A=
+			/// </summary>=0A=
+			internal DataTableRelationCollection (DataTable dataTable)=0A=
+			{=0A=
+				this.dataTable =3D dataTable;=0A=
+			}=0A=
+=0A=
+			/// <summary>=0A=
+			/// Gets the DataRelation object specified by name.=0A=
+			/// </summary>=0A=
+			public override DataRelation this [string name]=0A=
+			{=0A=
+				get {=0A=
+					foreach (DataRelation dataRelation in List)=0A=
+						if (dataRelation.RelationName =3D=3D name) return dataRelation;=0A=
+					return null;=0A=
+				}=0A=
+			}=0A=
+=0A=
+			/// <summary>=0A=
+			/// Gets the DataRelation object at the specified index.=0A=
+			/// </summary>=0A=
+			[MonoTODO]=0A=
+			public override DataRelation this [int index]=0A=
+			{=0A=
+				get {=0A=
+					return List [index] as DataRelation;=0A=
+				}=0A=
+			}=0A=
+=0A=
+			protected override DataSet GetDataSet()=0A=
+			{=0A=
+				return dataTable.DataSet;=0A=
+			}=0A=
+		}=0A=
+=0A=
 		private int defaultNameIndex;=0A=
 		private bool inTransition;=0A=
 		=0A=
@@ -55,6 +185,7 @@=0A=
 		[MonoTODO]=0A=
 		public void Add(DataRelation relation)=0A=
 		{=0A=
+			this.AddCore (relation);=0A=
 			if(List !=3D null)=0A=
 			{=0A=
 				//CollectionChangeEventArgs e =3D new =
CollectionChangeEventArgs(CollectionChangeAction.Add, this);=0A=
@@ -76,7 +207,6 @@=0A=
 		[MonoTODO]=0A=
 		public virtual DataRelation Add(DataColumn parentColumn, DataColumn =
childColumn)=0A=
 		{	=0A=
-			=0A=
 			if(parentColumn =3D=3D null)=0A=
 			{=0A=
 				throw new ArgumentNullException("parentColumn");=0A=
@@ -95,6 +225,7 @@=0A=
 			*/=0A=
 			=0A=
 			DataRelation dataRelation =3D new DataRelation("Relation" + =
defaultNameIndex.ToString(), parentColumn, childColumn);=0A=
+			this.AddCore (dataRelation);=0A=
 			//CollectionChangeEventArgs e =3D new =
CollectionChangeEventArgs(CollectionChangeAction.Add, this);=0A=
 			List.Add(dataRelation);=0A=
 			//OnCollectionChanged(e);=0A=
@@ -115,6 +246,7 @@=0A=
 		public virtual DataRelation Add(DataColumn[] parentColumns, =
DataColumn[] childColumns)=0A=
 		{=0A=
 			DataRelation dataRelation =3D new DataRelation("Relation" + =
defaultNameIndex.ToString(), parentColumns, childColumns);=0A=
+			this.AddCore (dataRelation);=0A=
 			List.Add(dataRelation);=0A=
 			defaultNameIndex++;=0A=
 			return dataRelation;=0A=
@@ -142,6 +274,7 @@=0A=
 			}=0A=
 =0A=
 			DataRelation dataRelation =3D new DataRelation(name, parentColumn, =
childColumn);=0A=
+			this.AddCore (dataRelation);=0A=
 			List.Add(dataRelation);=0A=
 			return dataRelation;=0A=
 		}=0A=
@@ -164,6 +297,7 @@=0A=
 			}=0A=
 =0A=
 			DataRelation dataRelation =3D new DataRelation(name, parentColumns, =
childColumns);=0A=
+			this.AddCore (dataRelation);=0A=
 			List.Add(dataRelation);=0A=
 			return dataRelation;=0A=
 		}=0A=
@@ -191,6 +325,7 @@=0A=
 			}=0A=
 =0A=
 			DataRelation dataRelation =3D new DataRelation(name, parentColumn, =
childColumn, createConstraints);=0A=
+			this.AddCore (dataRelation);=0A=
 			List.Add(dataRelation);=0A=
 			return dataRelation;=0A=
 		}=0A=
@@ -215,7 +350,7 @@=0A=
 			}=0A=
 =0A=
 			DataRelation dataRelation =3D new DataRelation(name, parentColumns, =
childColumns, createConstraints);=0A=
-			AddCore(dataRelation);=0A=
+			AddCore (dataRelation);=0A=
 			List.Add(dataRelation);=0A=
 			return dataRelation;=0A=
 		}=0A=
@@ -316,7 +451,7 @@=0A=
 =0A=
 		public void Remove (DataRelation relation)=0A=
 		{=0A=
-			RemoveCore (relation);=0A=
+			// TODO: RemoveCore (relation);=0A=
 			List.Remove (relation);=0A=
 			OnCollectionChanged (CreateCollectionChangeEvent =
(CollectionChangeAction.Remove));=0A=
 		}=0A=
Index: System.Data/DataRow.cs=0A=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=0A=
RCS file: /mono/mcs/class/System.Data/System.Data/DataRow.cs,v=0A=
retrieving revision 1.30=0A=
diff -u -r1.30 DataRow.cs=0A=
--- System.Data/DataRow.cs	26 Jan 2003 13:38:41 -0000	1.30=0A=
+++ System.Data/DataRow.cs	17 Feb 2003 17:07:31 -0000=0A=
@@ -555,20 +555,18 @@=0A=
 		/// <summary>=0A=
 		/// Gets the child rows of this DataRow using the specified =
DataRelation.=0A=
 		/// </summary>=0A=
-		[MonoTODO]=0A=
 		public DataRow[] GetChildRows (DataRelation relation) =0A=
 		{=0A=
-			throw new NotImplementedException ();=0A=
+			return GetChildRows (relation, DataRowVersion.Current);=0A=
 		}=0A=
 =0A=
 		/// <summary>=0A=
 		/// Gets the child rows of a DataRow using the specified RelationName =
of a=0A=
 		/// DataRelation.=0A=
 		/// </summary>=0A=
-		[MonoTODO]=0A=
 		public DataRow[] GetChildRows (string relationName) =0A=
 		{=0A=
-			throw new NotImplementedException ();=0A=
+			return GetChildRows (Table.DataSet.Relations[relationName]);=0A=
 		}=0A=
 =0A=
 		/// <summary>=0A=
@@ -578,17 +576,32 @@=0A=
 		[MonoTODO]=0A=
 		public DataRow[] GetChildRows (DataRelation relation, DataRowVersion =
version) =0A=
 		{=0A=
-			throw new NotImplementedException ();=0A=
+			// TODO: Caching for better preformance=0A=
+			ArrayList rows =3D new ArrayList();=0A=
+			DataColumn[] parentColumns =3D relation.ParentColumns;=0A=
+			DataColumn[] childColumns =3D relation.ChildColumns;=0A=
+			int numColumn =3D parentColumns.Length;=0A=
+			foreach (DataRow row in relation.ChildTable.Rows) {=0A=
+				bool allColumnsMatch =3D true;=0A=
+				for (int columnCnt =3D 0; columnCnt < numColumn; ++columnCnt) {=0A=
+					if (!this [parentColumns[columnCnt], version].Equals(=0A=
+					    row[childColumns[columnCnt], version])) {=0A=
+						allColumnsMatch =3D false;=0A=
+						break;=0A=
+					}=0A=
+				}=0A=
+				if (allColumnsMatch) rows.Add(row);=0A=
+			}=0A=
+			return rows.ToArray(typeof(DataRow)) as DataRow[];=0A=
 		}=0A=
 =0A=
 		/// <summary>=0A=
 		/// Gets the child rows of a DataRow using the specified RelationName =
of a=0A=
 		/// DataRelation, and DataRowVersion.=0A=
 		/// </summary>=0A=
-		[MonoTODO]=0A=
 		public DataRow[] GetChildRows (string relationName, DataRowVersion =
version) =0A=
 		{=0A=
-			throw new NotImplementedException ();=0A=
+			return GetChildRows (Table.DataSet.Relations[relationName], version);=0A=
 		}=0A=
 =0A=
 		/// <summary>=0A=
Index: System.Data/DataSet.cs=0A=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=0A=
RCS file: /mono/mcs/class/System.Data/System.Data/DataSet.cs,v=0A=
retrieving revision 1.33=0A=
diff -u -r1.33 DataSet.cs=0A=
--- System.Data/DataSet.cs	5 Feb 2003 15:48:57 -0000	1.33=0A=
+++ System.Data/DataSet.cs	17 Feb 2003 17:07:33 -0000=0A=
@@ -37,7 +37,7 @@=0A=
 		private bool caseSensitive;=0A=
 		private bool enforceConstraints =3D true;=0A=
 		private DataTableCollection tableCollection;=0A=
-		// private DataTableRelationCollection relationCollection;=0A=
+		private DataRelationCollection relationCollection;=0A=
 		private PropertyCollection properties;=0A=
 		private DataViewManager defaultView;=0A=
 		private CultureInfo locale;=0A=
@@ -52,7 +52,7 @@=0A=
 		public DataSet(string name) {=0A=
 			dataSetName =3D name;=0A=
 			tableCollection =3D new DataTableCollection (this);=0A=
-			//relationCollection =3D new DataTableRelationCollection ();=0A=
+			relationCollection =3D new =
DataRelationCollection.DataSetRelationCollection (this);=0A=
 		}=0A=
 =0A=
 		[MonoTODO]=0A=
@@ -201,10 +201,8 @@=0A=
 		[DataSysDescription ("The collection that holds the relations for =
this DatSet.")]=0A=
 		[DesignerSerializationVisibility =
(DesignerSerializationVisibility.Content)]=0A=
 		public DataRelationCollection Relations {=0A=
-			[MonoTODO]=0A=
-			get{=0A=
-				//return relationCollection;		=0A=
-				throw new NotImplementedException ();		=0A=
+			get {=0A=
+				return relationCollection;		=0A=
 			}=0A=
 		}=0A=
 =0A=
@@ -389,10 +387,8 @@=0A=
 			//Write out each table in order, providing it is not=0A=
 			//part of another table structure via a nested parent relationship=0A=
 			foreach( DataTable table in Tables )=0A=
-			{		=0A=
+			{=0A=
 				bool isTopLevel =3D true;=0A=
-				//FIXME: Uncomment this when Parentrelations is implemented=0A=
-				/*=0A=
 				foreach( DataRelation rel in table.ParentRelations )=0A=
 				{=0A=
 					if( rel.Nested )=0A=
@@ -401,7 +397,6 @@=0A=
 						break;=0A=
 					}=0A=
 				}=0A=
-				*/=0A=
 				=0A=
 				if( isTopLevel )=0A=
 				{=0A=
@@ -599,7 +594,7 @@=0A=
 		#endregion=0A=
 		=0A=
 		#region Protected Methods=0A=
-		protected virtual void GetSerializationData(SerializationInfo info, =
StreamingContext context)=0A=
+		protected void GetSerializationData(SerializationInfo info, =
StreamingContext context)=0A=
 		{=0A=
 			string s =3D info.GetValue ("XmlDiffGram", typeof (String)) as =
String;=0A=
 			if (s !=3D null) ReadXmlSerializable (new XmlTextReader(new =
StringReader(s)));=0A=
@@ -630,15 +625,24 @@=0A=
 	=0A=
 		private void WriteTable( XmlWriter writer, DataTable table, =
XmlWriteMode mode )=0A=
 		{=0A=
+			DataRow[] rows =3D new DataRow [table.Rows.Count];=0A=
+			table.Rows.CopyTo (rows, 0);=0A=
+			WriteTable (writer, rows, mode);=0A=
+		}=0A=
+=0A=
+		private void WriteTable( XmlWriter writer, DataRow[] rows, =
XmlWriteMode mode )=0A=
+		{=0A=
 			//The columns can be attributes, hidden, elements, or simple content=0A=
 			//There can be 0-1 simple content cols or 0-* elements=0A=
 			System.Collections.ArrayList atts;=0A=
 			System.Collections.ArrayList elements;=0A=
 			DataColumn simple =3D null;=0A=
 =0A=
+			if (rows.Length =3D=3D 0) return;=0A=
+			DataTable table =3D rows[0].Table;=0A=
 			SplitColumns( table, out atts, out elements, out simple );=0A=
 =0A=
-			foreach( DataRow row in table.Rows )=0A=
+			foreach( DataRow row in rows )=0A=
 			{=0A=
 				//sort out the namespacing=0A=
 				string nspc =3D table.Namespace.Length > 0 ? table.Namespace : =
Namespace;=0A=
@@ -692,7 +696,11 @@=0A=
 					}=0A=
 				}=0A=
 				=0A=
-				//TODO write out the nested child relations=0A=
+				foreach (DataRelation relation in table.ChildRelations) {=0A=
+					if (relation.Nested) {=0A=
+						WriteTable (writer, row.GetChildRows(relation), mode);=0A=
+					}=0A=
+				}=0A=
 				=0A=
 				writer.WriteEndElement();=0A=
 			}=0A=
@@ -788,12 +796,9 @@=0A=
 			=0A=
 			//Write out schema for each table in order, providing it is not=0A=
 			//part of another table structure via a nested parent relationship=0A=
-			//TODO - is this correct? should I be using nested objects?=0A=
 			foreach( DataTable table in Tables )=0A=
 			{		=0A=
 				bool isTopLevel =3D true;=0A=
-				//FIXME: Uncomment this when ParentRelations class is implemented=0A=
-				/*=0A=
 				foreach( DataRelation rel in table.ParentRelations )=0A=
 				{=0A=
 					if( rel.Nested )=0A=
@@ -802,7 +807,6 @@=0A=
 						break;=0A=
 					}=0A=
 				}=0A=
-				*/=0A=
 				=0A=
 				if( isTopLevel )=0A=
 				{=0A=
Index: System.Data/DataTable.cs=0A=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=0A=
RCS file: /mono/mcs/class/System.Data/System.Data/DataTable.cs,v=0A=
retrieving revision 1.28=0A=
diff -u -r1.28 DataTable.cs=0A=
--- System.Data/DataTable.cs	5 Feb 2003 15:48:57 -0000	1.28=0A=
+++ System.Data/DataTable.cs	17 Feb 2003 17:07:35 -0000=0A=
@@ -40,9 +40,8 @@=0A=
 		private CultureInfo _locale;=0A=
 		private int _minimumCapacity;=0A=
 		private string _nameSpace;=0A=
-		// FIXME: temporarily commented=0A=
-		// private DataTableRelationCollection _childRelations; =0A=
-		// private DataTableRelationCollection _parentRelations;=0A=
+		private DataRelationCollection _childRelations; =0A=
+		private DataRelationCollection _parentRelations;=0A=
 		private string _prefix;=0A=
 		private DataColumn[] _primaryKey;=0A=
 		private DataRowCollection _rows;=0A=
@@ -73,9 +72,8 @@=0A=
 			//LAMESPEC: spec says 25 impl does 50=0A=
 			_minimumCapacity =3D 50;=0A=
 			=0A=
-			// FIXME: temporaily commented DataTableRelationCollection=0A=
-			// _childRelations =3D new DataTableRelationCollection();=0A=
-			// _parentRelations =3D new DataTableRelationCollection();=0A=
+			_childRelations =3D new =
DataRelationCollection.DataTableRelationCollection (this);=0A=
+			_parentRelations =3D new =
DataRelationCollection.DataTableRelationCollection (this);=0A=
 =0A=
 		=0A=
 			_defaultView =3D new DataView(this);=0A=
@@ -146,13 +144,7 @@=0A=
 		[DesignerSerializationVisibility =
(DesignerSerializationVisibility.Hidden)]=0A=
 		public DataRelationCollection ChildRelations {=0A=
 			get {=0A=
-				// FIXME: temporarily commented to compile=0A=
-				// return (DataRelationCollection)_childRelations;=0A=
-				=0A=
-				//We are going to have to Inherit a class from =0A=
-				//DataRelationCollection because DRC is abstract=0A=
-				=0A=
-				throw new NotImplementedException ();=0A=
+				return _childRelations;=0A=
 			}=0A=
 		}=0A=
 =0A=
@@ -275,9 +267,7 @@=0A=
 		[DesignerSerializationVisibility =
(DesignerSerializationVisibility.Hidden)]=0A=
 		public DataRelationCollection ParentRelations {=0A=
 			get {	=0A=
-				// FIXME: temporarily commented to compile=0A=
-				// return _parentRelations;=0A=
-				throw new NotImplementedException ();=0A=
+				return _parentRelations;=0A=
 			}=0A=
 		}=0A=
=0A=

------=_NextPart_000_001B_01C2D6EF.BA257520--