2 // System.Data.DataColumn.cs
\r
5 // Franklin Wise (gracenote@earthlink.net)
\r
6 // Christopher Podurgiel (cpodurgiel@msn.com)
\r
7 // Rodrigo Moya (rodrigo@ximian.com)
\r
8 // Daniel Morgan (danmorg@sc.rr.com)
\r
9 // Tim Coleman (tim@timcoleman.com)
\r
11 // (C) Copyright 2002, Franklin Wise
\r
12 // (C) Chris Podurgiel
\r
13 // (C) Ximian, Inc 2002
\r
14 // Copyright (C) Tim Coleman, 2002
\r
15 // Copyright (C) Daniel Morgan, 2002, 2003
\r
19 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
\r
21 // Permission is hereby granted, free of charge, to any person obtaining
\r
22 // a copy of this software and associated documentation files (the
\r
23 // "Software"), to deal in the Software without restriction, including
\r
24 // without limitation the rights to use, copy, modify, merge, publish,
\r
25 // distribute, sublicense, and/or sell copies of the Software, and to
\r
26 // permit persons to whom the Software is furnished to do so, subject to
\r
27 // the following conditions:
\r
29 // The above copyright notice and this permission notice shall be
\r
30 // included in all copies or substantial portions of the Software.
\r
32 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
\r
33 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
\r
34 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
\r
35 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
\r
36 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
\r
37 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
\r
38 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
\r
42 using System.ComponentModel;
\r
43 using System.Reflection;
\r
44 using System.Collections;
\r
45 using System.Data.Common;
\r
46 using System.Globalization;
\r
47 using Mono.Data.SqlExpressions;
\r
49 namespace System.Data {
\r
50 internal delegate void DelegateColumnValueChange(DataColumn column, DataRow row, object proposedValue);
\r
53 /// Summary description for DataColumn.
\r
56 [Editor ("Microsoft.VSDesigner.Data.Design.DataColumnEditor, " + Consts.AssemblyMicrosoft_VSDesigner,
\r
57 "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
\r
58 [ToolboxItem (false)]
\r
59 [DefaultProperty ("ColumnName")]
\r
60 [DesignTimeVisible (false)]
\r
61 public class DataColumn : MarshalByValueComponent
\r
65 //used for constraint validation
\r
66 //if an exception is fired during this event the change should be canceled
\r
67 internal event DelegateColumnValueChange ValidateColumnValueChange;
\r
69 //used for FK Constraint Cascading rules
\r
70 internal event DelegateColumnValueChange ColumnValueChanging;
\r
72 internal event PropertyChangedEventHandler PropertyChanged;
\r
77 private bool _allowDBNull = true;
\r
78 private bool _autoIncrement;
\r
79 private long _autoIncrementSeed;
\r
80 private long _autoIncrementStep = 1;
\r
81 private long _nextAutoIncrementValue;
\r
82 private string _caption;
\r
83 private MappingType _columnMapping;
\r
84 private string _columnName = String.Empty;
\r
85 private object _defaultValue = DBNull.Value;
\r
86 private string _expression;
\r
87 private IExpression _compiledExpression;
\r
88 private PropertyCollection _extendedProperties = new PropertyCollection ();
\r
89 private int _maxLength = -1; //-1 represents no length limit
\r
90 private string _nameSpace;
\r
91 private int _ordinal = -1; //-1 represents not part of a collection
\r
92 private string _prefix = String.Empty;
\r
93 private bool _readOnly;
\r
94 private DataTable _table;
\r
95 private bool _unique;
\r
96 private AbstractDataContainer _dataContainer;
\r
98 #endregion // Fields
\r
100 #region Constructors
\r
102 public DataColumn() : this(String.Empty, typeof (string), String.Empty, MappingType.Element)
\r
106 //TODO: Ctor init vars directly
\r
107 public DataColumn(string columnName): this(columnName, typeof (string), String.Empty, MappingType.Element)
\r
111 public DataColumn(string columnName, Type dataType): this(columnName, dataType, String.Empty, MappingType.Element)
\r
115 public DataColumn( string columnName, Type dataType,
\r
116 string expr): this(columnName, dataType, expr, MappingType.Element)
\r
120 public DataColumn(string columnName, Type dataType,
\r
121 string expr, MappingType type)
\r
123 ColumnName = (columnName == null ? String.Empty : columnName);
\r
125 if(dataType == null) {
\r
126 throw new ArgumentNullException("dataType can't be null.");
\r
129 DataType = dataType;
\r
130 Expression = expr == null ? String.Empty : expr;
\r
131 ColumnMapping = type;
\r
137 internal object this[int index] {
\r
139 return DataContainer[index];
\r
142 if ( !(value == null && AutoIncrement) ) {
\r
144 DataContainer[index] = value;
\r
146 catch(Exception e) {
\r
147 throw new ArgumentException(e.Message +
\r
148 String.Format("Couldn't store <{0}> in {1} Column. Expected type is {2}.",
\r
149 value, ColumnName, DataType.Name), e);
\r
153 if ( AutoIncrement && !DataContainer.IsNull(index) ) {
\r
154 long value64 = Convert.ToInt64(value);
\r
155 UpdateAutoIncrementValue(value64);
\r
161 DataSetDateTime _datetimeMode = DataSetDateTime.UnspecifiedLocal;
\r
162 [DefaultValue (DataSetDateTime.UnspecifiedLocal)]
\r
163 [RefreshProperties (RefreshProperties.All)]
\r
164 public DataSetDateTime DateTimeMode {
\r
165 get { return _datetimeMode; }
\r
167 if (DataType != typeof (DateTime))
\r
168 throw new InvalidOperationException ("The DateTimeMode can be set only on DataColumns of type DateTime.");
\r
170 if (!Enum.IsDefined (typeof (DataSetDateTime), value))
\r
171 throw new InvalidEnumArgumentException ("The DataSetDateTime enumeration value, " +
\r
172 (int)value + ", is invalid.");
\r
174 if (_datetimeMode == value)
\r
176 if (_table == null || _table.Rows.Count == 0) {
\r
177 _datetimeMode = value;
\r
180 if ((_datetimeMode == DataSetDateTime.Unspecified || _datetimeMode == DataSetDateTime.UnspecifiedLocal)
\r
181 && (value == DataSetDateTime.Unspecified || value == DataSetDateTime.UnspecifiedLocal)) {
\r
182 _datetimeMode = value;
\r
186 throw new InvalidOperationException ( String.Format (
\r
187 "Cannot change DateTimeMode from '{0}' to '{1}' " +
\r
188 "once the table has data.",_datetimeMode, value));
\r
193 [DataCategory ("Data")]
\r
195 [DataSysDescription ("Indicates whether null values are allowed in this column.")]
\r
197 [DefaultValue (true)]
\r
198 public bool AllowDBNull
\r
201 return _allowDBNull;
\r
204 //TODO: If we are a part of the table and this value changes
\r
205 //we need to validate that all the existing values conform to the new setting
\r
209 _allowDBNull = true;
\r
213 //if Value == false case
\r
214 if (null != _table)
\r
216 if (_table.Rows.Count > 0)
\r
218 bool nullsFound = false;
\r
219 for(int r = 0; r < _table.Rows.Count; r++) {
\r
220 DataRow row = _table.Rows[r];
\r
221 if(row.IsNull(this)) {
\r
228 throw new DataException("Column '" + ColumnName + "' has null values in it.");
\r
229 //TODO: Validate no null values exist
\r
230 //do we also check different versions of the row??
\r
234 _allowDBNull = value;
\r
239 /// Gets or sets a value indicating whether the column automatically increments the value of the column for new rows added to the table.
\r
242 /// If the type of this column is not Int16, Int32, or Int64 when this property is set,
\r
243 /// the DataType property is coerced to Int32. An exception is generated if this is a computed column
\r
244 /// (that is, the Expression property is set.) The incremented value is used only if the row's value for this column,
\r
245 /// when added to the columns collection, is equal to the default value.
\r
247 [DataCategory ("Data")]
\r
249 [DataSysDescription ("Indicates whether the column automatically increments itself for new rows added to the table. The type of this column must be Int16, Int32, or Int64.")]
\r
251 [DefaultValue (false)]
\r
252 [RefreshProperties (RefreshProperties.All)]
\r
253 public bool AutoIncrement
\r
256 return _autoIncrement;
\r
261 //Can't be true if this is a computed column
\r
262 if (Expression != string.Empty)
\r
264 throw new ArgumentException("Can not Auto Increment a computed column.");
\r
267 if ( DefaultValue != DBNull.Value ) {
\r
268 throw new ArgumentException("Can not set AutoIncrement while" +
\r
269 " default value exists for this column.");
\r
272 if(!CanAutoIncrement(DataType))
\r
274 DataType = typeof(Int32);
\r
277 if (_table != null)
\r
278 _table.Columns.UpdateAutoIncrement(this,true);
\r
282 if (_table != null)
\r
283 _table.Columns.UpdateAutoIncrement(this,false);
\r
285 _autoIncrement = value;
\r
289 [DataCategory ("Data")]
\r
291 [DataSysDescription ("Indicates the starting value for an AutoIncrement column.")]
\r
294 public long AutoIncrementSeed
\r
297 return _autoIncrementSeed;
\r
300 _autoIncrementSeed = value;
\r
301 _nextAutoIncrementValue = _autoIncrementSeed;
\r
305 [DataCategory ("Data")]
\r
307 [DataSysDescription ("Indicates the increment used by an AutoIncrement column.")]
\r
310 public long AutoIncrementStep
\r
313 return _autoIncrementStep;
\r
316 _autoIncrementStep = value;
\r
320 internal void UpdateAutoIncrementValue(long value64)
\r
322 if (_autoIncrementStep > 0 ) {
\r
323 if (value64 >= _nextAutoIncrementValue) {
\r
324 _nextAutoIncrementValue = value64;
\r
325 AutoIncrementValue ();
\r
328 else if (value64 <= _nextAutoIncrementValue) {
\r
329 AutoIncrementValue ();
\r
333 internal long AutoIncrementValue ()
\r
335 long currentValue = _nextAutoIncrementValue;
\r
336 _nextAutoIncrementValue += AutoIncrementStep;
\r
337 return currentValue;
\r
340 internal long GetAutoIncrementValue ()
\r
342 return _nextAutoIncrementValue;
\r
345 internal void SetDefaultValue(int index) {
\r
347 this[index] = _nextAutoIncrementValue;
\r
349 DataContainer.CopyValue(Table.DefaultValuesRowIndex, index);
\r
352 [DataCategory ("Data")]
\r
354 [DataSysDescription ("Indicates the default user-interface caption for this column.")]
\r
356 public string Caption
\r
359 if(_caption == null)
\r
366 value = String.Empty;
\r
373 [DataSysDescription ("Indicates how this column persists in XML: as an attribute, element, simple content node, or nothing.")]
\r
375 [DefaultValue (MappingType.Element)]
\r
376 public virtual MappingType ColumnMapping
\r
379 return _columnMapping;
\r
382 _columnMapping = value;
\r
386 [DataCategory ("Data")]
\r
388 [DataSysDescription ("Indicates the name used to look up this column in the Columns collection of a DataTable.")]
\r
390 [RefreshProperties (RefreshProperties.All)]
\r
391 [DefaultValue ("")]
\r
392 public string ColumnName
\r
395 return _columnName;
\r
399 value = String.Empty;
\r
401 CultureInfo info = Table != null ? Table.Locale : CultureInfo.CurrentCulture;
\r
402 if (String.Compare(value, _columnName, true, info) != 0) {
\r
403 if (Table != null) {
\r
404 if (value.Length == 0)
\r
405 throw new ArgumentException("ColumnName is required when it is part of a DataTable.");
\r
407 Table.Columns.RegisterName(value, this);
\r
408 if (_columnName.Length > 0)
\r
409 Table.Columns.UnregisterName(_columnName);
\r
412 RaisePropertyChanging("ColumnName");
\r
413 _columnName = value;
\r
416 Table.ResetPropertyDescriptorsCache();
\r
418 else if (String.Compare(value, _columnName, false, info) != 0) {
\r
419 RaisePropertyChanging("ColumnName");
\r
420 _columnName = value;
\r
423 Table.ResetPropertyDescriptorsCache();
\r
428 [DataCategory ("Data")]
\r
430 [DataSysDescription ("Indicates the type of data stored in this column.")]
\r
432 [DefaultValue (typeof (string))]
\r
433 [RefreshProperties (RefreshProperties.All)]
\r
434 [TypeConverterAttribute (typeof (ColumnTypeConverter))]
\r
435 public Type DataType
\r
438 return DataContainer.Type;
\r
442 if ( value == null )
\r
445 if ( _dataContainer != null ) {
\r
446 if ( value == _dataContainer.Type )
\r
449 // check if data already exists can we change the datatype
\r
450 if ( _dataContainer.Capacity > 0 )
\r
451 throw new ArgumentException("The column already has data stored.");
\r
454 if (null != GetParentRelation () || null != GetChildRelation ())
\r
455 throw new InvalidConstraintException ("Cannot change datatype, " +
\r
456 "when column is part of a relation");
\r
459 if (_dataContainer != null && _dataContainer.Type == typeof (DateTime))
\r
460 _datetimeMode = DataSetDateTime.UnspecifiedLocal;
\r
462 _dataContainer = AbstractDataContainer.CreateInstance(value, this);
\r
464 //Check AutoIncrement status, make compatible datatype
\r
465 if(AutoIncrement == true) {
\r
466 // we want to check that the datatype is supported?
\r
467 TypeCode typeCode = Type.GetTypeCode(value);
\r
469 if(typeCode != TypeCode.Int16 &&
\r
470 typeCode != TypeCode.Int32 &&
\r
471 typeCode != TypeCode.Int64) {
\r
472 AutoIncrement = false;
\r
481 /// <remarks>When AutoIncrement is set to true, there can be no default value.</remarks>
\r
482 /// <exception cref="System.InvalidCastException"></exception>
\r
483 /// <exception cref="System.ArgumentException"></exception>
\r
484 [DataCategory ("Data")]
\r
486 [DataSysDescription ("Indicates the default column value used when adding new rows to the table.")]
\r
488 [TypeConverterAttribute (typeof (System.Data.DefaultValueTypeConverter))]
\r
489 public object DefaultValue
\r
492 return _defaultValue;
\r
496 if (AutoIncrement) {
\r
497 throw new ArgumentException("Can not set default value while" +
\r
498 " AutoIncrement is true on this column.");
\r
502 if (!this._defaultValue.Equals(value)) {
\r
503 if (value == null) {
\r
504 tmpObj = DBNull.Value;
\r
510 if ((this.DataType != typeof (object))&& (tmpObj != DBNull.Value)) {
\r
512 //Casting to the new type
\r
513 tmpObj= Convert.ChangeType(tmpObj,this.DataType);
\r
515 catch (InvalidCastException) {
\r
516 throw new InvalidCastException("Default Value type is not compatible with" +
\r
520 _defaultValue = tmpObj;
\r
523 // store default value in the table if already belongs to
\r
524 if (Table != null && Table.DefaultValuesRowIndex != -1) {
\r
525 DataContainer[Table.DefaultValuesRowIndex] = _defaultValue;
\r
530 [DataCategory ("Data")]
\r
532 [DataSysDescription ("Indicates the value that this column computes for each row based on other columns instead of taking user input.")]
\r
534 [DefaultValue ("")]
\r
535 [RefreshProperties (RefreshProperties.All)]
\r
536 public string Expression
\r
539 return _expression;
\r
543 value = String.Empty;
\r
545 if (value != String.Empty)
\r
548 if (AutoIncrement || Unique)
\r
549 throw new ArgumentException("Cannot create an expression on a column that has AutoIncrement or Unique.");
\r
553 for (int i = 0; i < Table.Constraints.Count; i++)
\r
555 if (Table.Constraints[i].IsColumnContained(this))
\r
556 throw new ArgumentException(String.Format("Cannot set Expression property on column {0}, because it is a part of a constraint.", ColumnName));
\r
560 Parser parser = new Parser ();
\r
561 IExpression compiledExpression = parser.Compile (value);
\r
565 if (compiledExpression.DependsOn(this))
\r
566 throw new ArgumentException("Cannot set Expression property due to circular reference in the expression.");
\r
567 // Check if expression is ok
\r
568 if (Table.Rows.Count == 0)
\r
569 compiledExpression.Eval (Table.NewRow());
\r
571 compiledExpression.Eval (Table.Rows[0]);
\r
574 _compiledExpression = compiledExpression;
\r
578 _compiledExpression = null;
\r
579 if (Table != null) {
\r
580 int defaultValuesRowIndex = Table.DefaultValuesRowIndex;
\r
581 if ( defaultValuesRowIndex != -1)
\r
582 DataContainer.FillValues(defaultValuesRowIndex);
\r
585 _expression = value;
\r
589 internal IExpression CompiledExpression {
\r
590 get { return _compiledExpression; }
\r
593 [Browsable (false)]
\r
594 [DataCategory ("Data")]
\r
596 [DataSysDescription ("The collection that holds custom user information.")]
\r
598 public PropertyCollection ExtendedProperties
\r
601 return _extendedProperties;
\r
604 internal set { _extendedProperties = value; }
\r
608 [DataCategory ("Data")]
\r
610 [DataSysDescription ("Indicates the maximum length of the value this column allows. ")]
\r
612 [DefaultValue (-1)]
\r
613 public int MaxLength
\r
616 //Default == -1 no max length
\r
621 _columnMapping == MappingType.SimpleContent)
\r
622 throw new ArgumentException (String.Format ("Cannot set MaxLength property on '{0}' column which is mapped to SimpleContent.", ColumnName));
\r
623 //only applies to string columns
\r
624 _maxLength = value;
\r
628 [DataCategory ("Data")]
\r
630 [DataSysDescription ("Indicates the XML uri for elements or attributes stored in this column.")]
\r
632 public string Namespace
\r
635 if (_nameSpace != null)
\r
639 if ((Table != null) && (_columnMapping != MappingType.Attribute))
\r
641 return Table.Namespace;
\r
643 return String.Empty;
\r
646 _nameSpace = value;
\r
650 //Need a good way to set the Ordinal when the column is added to a columnCollection.
\r
651 [Browsable (false)]
\r
652 [DataCategory ("Data")]
\r
654 [DataSysDescription ("Indicates the index of this column in the Columns collection.")]
\r
656 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
\r
657 public int Ordinal {
\r
658 get { return _ordinal; }
\r
660 internal set { _ordinal = value; }
\r
665 public void SetOrdinal (int ordinal)
\r
667 if (_ordinal == -1)
\r
668 throw new ArgumentException ("Column must belong to a table.");
\r
669 _table.Columns.MoveColumn (_ordinal, ordinal);
\r
670 _ordinal = ordinal;
\r
673 internal void SetOrdinal(int ordinal)
\r
675 _ordinal = ordinal;
\r
679 [DataCategory ("Data")]
\r
681 [DataSysDescription ("Indicates the Prefix used for this DataColumn in xml representation.")]
\r
683 [DefaultValue ("")]
\r
684 public string Prefix
\r
691 value = String.Empty;
\r
696 [DataCategory ("Data")]
\r
698 [DataSysDescription ("Indicates whether this column allows changes once a row has been added to the table.")]
\r
700 [DefaultValue (false)]
\r
701 public bool ReadOnly
\r
711 [Browsable (false)]
\r
712 [DataCategory ("Data")]
\r
714 [DataSysDescription ("Returns the DataTable to which this column belongs.")]
\r
716 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
\r
717 public DataTable Table
\r
724 [DataCategory ("Data")]
\r
726 [DataSysDescription ("Indicates whether this column should restrict its values in the rows of the table to be unique.")]
\r
728 [DefaultValue (false)]
\r
729 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
\r
730 public bool Unique
\r
737 if (_unique == value)
\r
740 // Set the property value, so that when adding/removing the constraint
\r
741 // we dont run into recursive issues.
\r
744 if (_table == null)
\r
749 if (Expression != null && Expression != String.Empty)
\r
750 throw new ArgumentException("Cannot change Unique property for the expression column.");
\r
752 _table.Constraints.Add(null, this, false);
\r
755 UniqueConstraint uc = UniqueConstraint.GetUniqueConstraintForColumnSet (_table.Constraints,
\r
756 new DataColumn[] {this});
\r
757 _table.Constraints.Remove (uc);
\r
759 } catch (Exception e) {
\r
766 internal AbstractDataContainer DataContainer {
\r
768 return _dataContainer;
\r
772 internal static bool CanAutoIncrement(Type type) {
\r
773 switch (Type.GetTypeCode(type)) {
\r
774 case TypeCode.Int16:
\r
775 case TypeCode.Int32:
\r
776 case TypeCode.Int64:
\r
777 case TypeCode.Decimal:
\r
784 #endregion // Properties
\r
790 protected internal void CheckNotAllowNull() {
\r
794 protected void CheckUnique() {
\r
798 internal DataColumn Clone() {
\r
799 DataColumn copy = new DataColumn ();
\r
801 // Copy all the properties of column
\r
802 copy._allowDBNull = _allowDBNull;
\r
803 copy._autoIncrement = _autoIncrement;
\r
804 copy._autoIncrementSeed = _autoIncrementSeed;
\r
805 copy._autoIncrementStep = _autoIncrementStep;
\r
806 copy._caption = _caption;
\r
807 copy._columnMapping = _columnMapping;
\r
808 copy._columnName = _columnName;
\r
810 copy.DataType = DataType;
\r
811 copy._defaultValue = _defaultValue;
\r
812 copy._expression = _expression;
\r
813 //Copy.ExtendedProperties
\r
814 copy._maxLength = _maxLength;
\r
815 copy._nameSpace = _nameSpace;
\r
816 copy._prefix = _prefix;
\r
817 copy._readOnly = _readOnly;
\r
819 //we do not copy the unique value - it will be copyied when copying the constraints.
\r
820 //Copy.Unique = Column.Unique;
\r
822 if (DataType == typeof (DateTime))
\r
823 copy.DateTimeMode = _datetimeMode;
\r
830 /// Sets unique true whithout creating Constraint
\r
832 internal void SetUnique()
\r
838 internal void AssertCanAddToCollection()
\r
840 //Check if Default Value is set and AutoInc is set
\r
844 protected internal void CheckNotAllowNull ()
\r
846 throw new NotImplementedException ();
\r
850 protected void CheckUnique ()
\r
852 throw new NotImplementedException ();
\r
855 protected internal virtual void
\r
856 OnPropertyChanging (PropertyChangedEventArgs pcevent) {
\r
857 if (PropertyChanged != null)
\r
858 PropertyChanged (this, pcevent);
\r
861 protected internal void RaisePropertyChanging(string name) {
\r
862 PropertyChangedEventArgs e = new PropertyChangedEventArgs (name);
\r
863 OnPropertyChanging (e);
\r
867 /// Gets the Expression of the column, if one exists.
\r
869 /// <returns>The Expression value, if the property is set;
\r
870 /// otherwise, the ColumnName property.</returns>
\r
871 public override string ToString()
\r
873 if (_expression != string.Empty)
\r
874 return ColumnName + " + " + _expression;
\r
879 internal void SetTable(DataTable table) {
\r
880 if(_table!=null) { // serves as double check while adding to a table
\r
881 throw new ArgumentException("The column already belongs to a different table");
\r
884 // this will get called by DataTable
\r
885 // and DataColumnCollection
\r
887 // if the DataColumn is marked as Unique and then
\r
888 // added to a DataTable , then a UniqueConstraint
\r
889 // should be created
\r
890 UniqueConstraint uc = new UniqueConstraint(this);
\r
891 _table.Constraints.Add(uc);
\r
894 // allocate space in the column data container
\r
895 DataContainer.Capacity = _table.RecordCache.CurrentCapacity;
\r
897 int defaultValuesRowIndex = _table.DefaultValuesRowIndex;
\r
898 if ( defaultValuesRowIndex != -1) {
\r
899 // store default value in the table
\r
900 DataContainer[defaultValuesRowIndex] = _defaultValue;
\r
901 // Set all the values in data container to default
\r
902 // it's cheaper that raise event on each row.
\r
903 DataContainer.FillValues(defaultValuesRowIndex);
\r
907 // Returns true if all the same collumns are in columnSet and compareSet
\r
908 internal static bool AreColumnSetsTheSame(DataColumn[] columnSet, DataColumn[] compareSet)
\r
910 if (null == columnSet && null == compareSet) {
\r
914 if (null == columnSet || null == compareSet) {
\r
918 if (columnSet.Length != compareSet.Length) {
\r
922 foreach (DataColumn col in columnSet) {
\r
923 bool matchFound = false;
\r
924 foreach (DataColumn compare in compareSet) {
\r
925 if (col == compare) {
\r
926 matchFound = true;
\r
929 if (! matchFound) {
\r
937 internal int CompareValues (int index1, int index2)
\r
939 return DataContainer.CompareValues(index1, index2);
\r
943 /// Returns the data relation, which contains this column.
\r
944 /// This searches in current table's parent relations.
\r
947 /// DataRelation if found otherwise null.
\r
949 private DataRelation GetParentRelation ()
\r
951 if (_table == null)
\r
953 foreach (DataRelation rel in _table.ParentRelations)
\r
954 if (rel.Contains (this))
\r
961 /// Returns the data relation, which contains this column.
\r
962 /// This searches in current table's child relations.
\r
965 /// DataRelation if found otherwise null.
\r
967 private DataRelation GetChildRelation ()
\r
969 if (_table == null)
\r
971 foreach (DataRelation rel in _table.ChildRelations)
\r
972 if (rel.Contains (this))
\r
977 internal void ResetColumnInfo ()
\r
981 if (_compiledExpression != null)
\r
982 _compiledExpression.ResetExpression ();
\r
985 internal bool DataTypeMatches (DataColumn col)
\r
987 if (DataType != col.DataType)
\r
990 if (DataType != typeof (DateTime))
\r
993 if (DateTimeMode == col.DateTimeMode)
\r
996 if (DateTimeMode == DataSetDateTime.Local || DateTimeMode == DataSetDateTime.Utc)
\r
999 if (col.DateTimeMode == DataSetDateTime.Local || col.DateTimeMode == DataSetDateTime.Utc)
\r
1004 #endregion // Methods
\r