2 // System.Data.DataTable.cs
5 // Franklin Wise <gracenote@earthlink.net>
6 // Christopher Podurgiel (cpodurgiel@msn.com)
7 // Daniel Morgan <danmorg@sc.rr.com>
8 // Rodrigo Moya <rodrigo@ximian.com>
10 // (C) Chris Podurgiel
11 // (C) Ximian, Inc 2002
15 using System.Collections;
16 using System.ComponentModel;
17 using System.Globalization;
18 using System.Runtime.Serialization;
23 /// Represents one table of in-memory data.
26 public class DataTable : ISerializable
27 //MarshalByValueComponent, IListSource, ISupportInitialize
29 internal DataSet dataSet;
31 private bool _caseSensitive;
32 private DataColumnCollection _columnCollection;
33 private ConstraintCollection _constraintCollection;
34 private DataView _defaultView;
36 private string _displayExpression;
37 private PropertyCollection _extendedProperties;
38 private bool _hasErrors;
39 private CultureInfo _locale;
40 private int _minimumCapacity;
41 private string _nameSpace;
42 // FIXME: temporarily commented
43 // private DataTableRelationCollection _childRelations;
44 // private DataTableRelationCollection _parentRelations;
45 private string _prefix;
46 private DataColumn[] _primaryKey;
47 private DataRowCollection _rows;
49 private string _tableName;
50 private bool _containsListCollection;
51 private string _encodedTableName;
54 /// Initializes a new instance of the DataTable class with no arguments.
60 _columnCollection = new DataColumnCollection(this);
61 _constraintCollection = new ConstraintCollection();
62 _extendedProperties = new PropertyCollection();
65 _caseSensitive = false; //default value
66 _displayExpression = null;
69 _rows = new DataRowCollection (this);
70 _locale = CultureInfo.CurrentCulture;
72 //LAMESPEC: spec says 25 impl does 50
73 _minimumCapacity = 50;
75 // FIXME: temporaily commented DataTableRelationCollection
76 // _childRelations = new DataTableRelationCollection();
77 // _parentRelations = new DataTableRelationCollection();
80 _defaultView = new DataView(this);
84 /// Intitalizes a new instance of the DataTable class with the specified table name.
87 public DataTable(string tableName) : this ()
89 _tableName = tableName;
93 /// Initializes a new instance of the DataTable class with the SerializationInfo and the StreamingContext.
97 protected DataTable(SerializationInfo info, StreamingContext context)
101 // TODO: Add constructor logic here
106 /// Indicates whether string comparisons within the table are case-sensitive.
109 public bool CaseSensitive
112 return _caseSensitive;
115 _caseSensitive = value;
121 /// Gets the collection of child relations for this DataTable.
124 public DataRelationCollection ChildRelations
127 // FIXME: temporarily commented to compile
128 // return (DataRelationCollection)_childRelations;
130 //We are going to have to Inherit a class from
131 //DataRelationCollection because DRC is abstract
133 throw new NotImplementedException ();
138 /// Gets the collection of columns that belong to this table.
141 public DataColumnCollection Columns
144 return _columnCollection;
149 /// Gets the collection of constraints maintained by this table.
152 public ConstraintCollection Constraints
155 return _constraintCollection;
160 /// Gets the DataSet that this table belongs to.
162 public DataSet DataSet {
163 get { return dataSet; }
169 /// Gets a customized view of the table which may
170 /// include a filtered view, or a cursor position.
173 public DataView DefaultView
183 /// Gets or sets the expression that will return
184 /// a value used to represent this table in the user interface.
187 public string DisplayExpression
190 return "" + _displayExpression;
193 _displayExpression = value;
198 /// Gets the collection of customized user information.
200 public PropertyCollection ExtendedProperties
203 return _extendedProperties;
208 /// Gets a value indicating whether there are errors in
209 /// any of the_rows in any of the tables of the DataSet to
210 /// which the table belongs.
212 public bool HasErrors
220 /// Gets or sets the locale information used to
221 /// compare strings within the table.
223 public CultureInfo Locale
234 /// Gets or sets the initial starting size for this table.
236 public int MinimumCapacity
239 return _minimumCapacity;
242 _minimumCapacity = value;
247 /// Gets or sets the namespace for the XML represenation
248 /// of the data stored in the DataTable.
250 public string Namespace
253 return "" + _nameSpace;
261 /// Gets the collection of parent relations for
265 public DataRelationCollection ParentRelations
268 // FIXME: temporarily commented to compile
269 // return _parentRelations;
270 throw new NotImplementedException ();
275 /// Gets or sets the namespace for the XML represenation
276 /// of the data stored in the DataTable.
289 /// Gets or sets an array of columns that function as
290 /// primary keys for the data table.
292 public DataColumn[] PrimaryKey
295 UniqueConstraint uc = UniqueConstraint.GetPrimaryKeyConstraint( Constraints);
296 if (null == uc) return new DataColumn[] {};
301 //YUK: msft removes a previous unique constraint if it is flagged as a pk
302 //when a new pk is set
304 //clear Primary Key if value == null
307 UniqueConstraint.SetAsPrimaryKey(this.Constraints, null);
312 //Does constraint exist for these columns
313 UniqueConstraint uc = UniqueConstraint.GetUniqueConstraintForColumnSet(
314 this.Constraints, (DataColumn[]) value);
316 //if constraint doesn't exist for columns
317 //create new unique primary key constraint
320 uc = new UniqueConstraint( (DataColumn[]) value, true);
322 else //set existing constraint as the new primary key
324 UniqueConstraint.SetAsPrimaryKey(this.Constraints, uc);
331 /// Gets the collection of_rows that belong to this table.
334 public DataRowCollection Rows
336 get { return _rows; }
340 /// Gets or sets an System.ComponentModel.ISite
341 /// for the DataTable.
344 public virtual ISite Site
355 /// Gets or sets the name of the the DataTable.
358 public string TableName
361 return "" + _tableName;
368 /* FIXME: implement IListSource
369 public bool IListSource.ContainsListCollection
372 return _containsListCollection;
378 /// Commits all the changes made to this table since the
379 /// last time AcceptChanges was called.
382 public void AcceptChanges()
385 //FIXME: Do we need to validate anything here or
386 //try to catch any errors to deal with them?
388 foreach(DataRow myRow in _rows)
390 myRow.AcceptChanges();
396 /// Begins the initialization of a DataTable that is used
397 /// on a form or used by another component. The initialization
398 /// occurs at runtime.
401 public void BeginInit()
406 /// Turns off notifications, index maintenance, and
407 /// constraints while loading data.
410 public void BeginLoadData()
415 /// Clears the DataTable of all data.
424 /// Clones the structure of the DataTable, including
425 /// all DataTable schemas and constraints.
429 public virtual DataTable Clone()
432 return this; //Don't know if this is correct
436 /// Computes the given expression on the current_rows that
437 /// pass the filter criteria.
441 public object Compute(string expression, string filter)
443 //FIXME: //Do a real compute
449 /// Copies both the structure and data for this DataTable.
452 public DataTable Copy()
454 //FIXME: Do a real copy
459 /// Ends the initialization of a DataTable that is used
460 /// on a form or used by another component. The
461 /// initialization occurs at runtime.
464 public void EndInit()
469 /// Turns on notifications, index maintenance, and
470 /// constraints after loading data.
473 public void EndLoadData()
478 /// Gets a copy of the DataTable that contains all
479 /// changes made to it since it was loaded or
480 /// AcceptChanges was last called.
483 public DataTable GetChanges()
490 /// Gets a copy of the DataTable containing all
491 /// changes made to it since it was last loaded, or
492 /// since AcceptChanges was called, filtered by DataRowState.
495 public DataTable GetChanges(DataRowState rowStates)
502 /// Gets an array of DataRow objects that contain errors.
506 public DataRow[] GetErrors()
508 throw new NotImplementedException ();
512 /// This member supports the .NET Framework infrastructure
513 /// and is not intended to be used directly from your code.
516 //protected virtual Type GetRowType()
521 /// This member supports the .NET Framework infrastructure
522 /// and is not intended to be used directly from your code.
525 /* FIXME: implement IListSource
526 public IList IListSource.GetList()
534 /// Copies a DataRow into a DataTable, preserving any
535 /// property settings, as well as original and current values.
538 public void ImportRow(DataRow row)
543 /// This member supports the .NET Framework infrastructure
544 /// and is not intended to be used directly from your code.
548 void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
553 /// Finds and updates a specific row. If no matching row
554 /// is found, a new row is created using the given values.
557 public DataRow LoadDataRow(object[] values, bool fAcceptChanges)
560 DataRow dataRow = null;
565 /// Creates a new DataRow with the same schema as the table.
567 public DataRow NewRow()
569 return this.NewRowFromBuilder (new DataRowBuilder (this, 0, 0));
573 /// This member supports the .NET Framework infrastructure
574 /// and is not intended to be used directly from your code.
577 protected internal DataRow[] NewRowArray(int size)
579 DataRow[] dataRows = {null};
584 /// Creates a new row from an existing row.
587 protected virtual DataRow NewRowFromBuilder(DataRowBuilder builder)
589 return new DataRow (builder);
594 /// Rolls back all changes that have been made to the
595 /// table since it was loaded, or the last time AcceptChanges
600 public void RejectChanges()
605 /// Resets the DataTable to its original state.
609 public virtual void Reset()
614 /// Gets an array of all DataRow objects.
618 public DataRow[] Select()
621 DataRow[] dataRows = {null};
626 /// Gets an array of all DataRow objects that match
627 /// the filter criteria in order of primary key (or
628 /// lacking one, order of addition.)
632 public DataRow[] Select(string filterExpression)
634 DataRow[] dataRows = {null};
639 /// Gets an array of all DataRow objects that
640 /// match the filter criteria, in the the
641 /// specified sort order.
644 public DataRow[] Select(string filterExpression, string sort)
646 DataRow[] dataRows = {null};
651 /// Gets an array of all DataRow objects that match
652 /// the filter in the order of the sort, that match
653 /// the specified state.
656 public DataRow[] Select(string filterExpression, string sort, DataViewRowState recordStates)
658 DataRow[] dataRows = {null};
663 /// Gets the TableName and DisplayExpression, if
664 /// there is one as a concatenated string.
666 public override string ToString()
668 //LAMESPEC: spec says concat the two. impl puts a
669 //plus sign infront of DisplayExpression
670 return TableName + " " + DisplayExpression;
674 #region Events /////////////////
677 /// Raises the ColumnChanged event.
679 protected virtual void OnColumnChanged(DataColumnChangeEventArgs e)
681 if (null != ColumnChanged)
683 ColumnChanged(this, e);
688 /// Raises the ColumnChanging event.
690 protected virtual void OnColumnChanging(DataColumnChangeEventArgs e)
692 if (null != ColumnChanging)
694 ColumnChanging(this, e);
699 /// Raises the PropertyChanging event.
702 protected internal virtual void OnPropertyChanging(PropertyChangedEventArgs pcevent)
704 // if (null != PropertyChanging)
706 // PropertyChanging(this, e);
711 /// Notifies the DataTable that a DataColumn is being removed.
714 protected internal virtual void OnRemoveColumn(DataColumn column)
716 // if (null != RemoveColumn)
718 // RemoveColumn(this, e);
723 /// Raises the RowChanged event.
726 protected virtual void OnRowChanged(DataRowChangeEventArgs e)
728 if (null != RowChanged)
735 /// Raises the RowChanging event.
738 protected virtual void OnRowChanging(DataRowChangeEventArgs e)
740 if (null != RowChanging)
742 RowChanging(this, e);
747 /// Raises the RowDeleted event.
749 protected virtual void OnRowDeleted(DataRowChangeEventArgs e)
751 if (null != RowDeleted)
758 /// Raises the RowDeleting event.
760 protected virtual void OnRowDeleting(DataRowChangeEventArgs e)
762 if (null != RowDeleting)
764 RowDeleting(this, e);
769 /// Occurs when after a value has been changed for
770 /// the specified DataColumn in a DataRow.
773 public event DataColumnChangeEventHandler ColumnChanged;
776 /// Occurs when a value is being changed for the specified
777 /// DataColumn in a DataRow.
780 public event DataColumnChangeEventHandler ColumnChanging;
783 /// Occurs after a DataRow has been changed successfully.
786 public event DataRowChangeEventHandler RowChanged;
789 /// Occurs when a DataRow is changing.
792 public event DataRowChangeEventHandler RowChanging;
795 /// Occurs after a row in the table has been deleted.
798 public event DataRowChangeEventHandler RowDeleted;
801 /// Occurs before a row in the table is about to be deleted.
804 public event DataRowChangeEventHandler RowDeleting;