2 // System.Data.DataRowCollection.cs
5 // Daniel Morgan <danmorg@sc.rr.com>
6 // Tim Coleman <tim@timcoleman.com>
8 // (C) Ximian, Inc 2002
9 // (C) Copyright 2002 Tim Coleman
10 // (C) Copyright 2002 Daniel Morgan
14 using System.Collections;
15 using System.ComponentModel;
20 /// Collection of DataRows in a DataTable
23 public class DataRowCollection : InternalDataCollectionBase
25 private DataTable table;
28 /// Internal constructor used to build a DataRowCollection.
30 internal DataRowCollection (DataTable table) : base ()
36 /// Gets the row at the specified index.
38 public DataRow this[int index]
42 throw new IndexOutOfRangeException ("There is no row at position " + index + ".");
44 return (DataRow) list[index];
49 /// This member overrides InternalDataCollectionBase.List
51 protected override ArrayList List
57 /// Adds the specified DataRow to the DataRowCollection object.
59 public void Add (DataRow row)
63 throw new ArgumentNullException("row", "'row' argument cannot be null.");
65 if (list.IndexOf(row) != -1)
66 throw new ArgumentException ("This row already belongs to this table.");
70 row.Table.ChangedDataRow (row, DataRowAction.Add);
74 /// Creates a row using specified values and adds it to the DataRowCollection.
76 public virtual DataRow Add (object[] values)
78 DataRow row = table.NewRow ();
79 row.ItemArray = values;
85 /// Clears the collection of all rows.
93 /// Gets a value indicating whether the primary key of any row in the collection contains
94 /// the specified value.
96 public bool Contains (object key)
98 return Find (key) != null;
102 /// Gets a value indicating whether the primary key column(s) of any row in the
103 /// collection contains the values specified in the object array.
105 public bool Contains (object[] keys)
107 if (table.PrimaryKey.Length != keys.Length)
108 throw new ArgumentException ("Expecting " + table.PrimaryKey.Length + " value(s) for the key " +
109 "being indexed, but received " + keys.Length + " value(s).");
111 return Find (keys) != null;
115 /// Gets the row specified by the primary key value.
118 public DataRow Find (object key)
120 if (table.PrimaryKey.Length == 0)
121 throw new MissingPrimaryKeyException ("Table doesn't have a primary key.");
122 if (table.PrimaryKey.Length > 1)
123 throw new ArgumentException ("Expecting " + table.PrimaryKey.Length +
124 " value(s) for the key being indexed, but received 1 value(s).");
126 string primColumnName = table.PrimaryKey [0].ColumnName;
128 object newKey = null;
130 foreach (DataRow row in this) {
132 object primValue = row [primColumnName];
134 if (primValue == null)
140 newKey = Convert.ChangeType (key, Type.GetTypeCode(primValue.GetType ()));
142 if (primValue.Equals (newKey))
146 // FIXME: is the correct value null?
151 /// Gets the row containing the specified primary key values.
154 public DataRow Find (object[] keys)
156 if (table.PrimaryKey.Length == 0)
157 throw new MissingPrimaryKeyException ("Table doesn't have a primary key.");
159 string [] primColumnNames = new string [table.PrimaryKey.Length];
161 for (int i = 0; i < primColumnNames.Length; i++)
162 primColumnNames [i] = table.PrimaryKey [i].ColumnName;
165 object newKey = null;
167 foreach (DataRow row in this) {
170 for (int i = 0; i < keys.Length; i++) {
172 object primValue = row [primColumnNames [i]];
173 object keyValue = keys [i];
174 if (keyValue == null) {
175 if (primValue == null)
181 newKey = Convert.ChangeType (keyValue, Type.GetTypeCode(primValue.GetType ()));
183 if (!primValue.Equals (newKey)) {
193 // FIXME: is the correct value null?
198 /// Inserts a new row into the collection at the specified location.
200 public void InsertAt (DataRow row, int pos)
203 throw new IndexOutOfRangeException ("The row insert position " + pos + " is invalid.");
205 if (pos >= list.Count)
208 list.Insert (pos, row);
212 /// Removes the specified DataRow from the collection.
214 public void Remove (DataRow row)
216 // FIXME: This is the way the MS.NET handles this kind of situation. Could be better, but what can you do.
217 if (row == null || list.IndexOf (row) == -1)
218 throw new IndexOutOfRangeException ("The given datarow is not in the current DataRowCollection.");
222 table.DeletedDataRow (row, DataRowAction.Delete);
226 /// Removes the row at the specified index from the collection.
228 public void RemoveAt (int index)
230 if (index < 0 || index >= list.Count)
231 throw new IndexOutOfRangeException ("There is no row at position " + index + ".");
233 DataRow row = (DataRow)list [index];
234 list.RemoveAt (index);
235 table.DeletedDataRow (row, DataRowAction.Delete);
239 ///Internal method used to validate a given DataRow with respect
240 ///to the DataRowCollection
243 internal void ValidateDataRowInternal(DataRow row)
245 //FIXME: this validates constraints in the order they appear
246 //in the collection. Most probably we need to do it in a
247 //specific order like unique/primary keys first, then Foreignkeys, etc
248 foreach(Constraint constraint in table.Constraints)
250 constraint.AssertConstraint(row);