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(String.Format("{0}. Couldn't store <{1}> in Column named '{2}'. Expected type is {3}.",
\r
148 e.Message, value, ColumnName, DataType.Name), e);
\r
152 if ( AutoIncrement && !DataContainer.IsNull(index) ) {
\r
153 long value64 = Convert.ToInt64(value);
\r
154 UpdateAutoIncrementValue(value64);
\r
160 DataSetDateTime _datetimeMode = DataSetDateTime.UnspecifiedLocal;
\r
161 [DefaultValue (DataSetDateTime.UnspecifiedLocal)]
\r
162 [RefreshProperties (RefreshProperties.All)]
\r
163 public DataSetDateTime DateTimeMode {
\r
164 get { return _datetimeMode; }
\r
166 if (DataType != typeof (DateTime))
\r
167 throw new InvalidOperationException ("The DateTimeMode can be set only on DataColumns of type DateTime.");
\r
169 if (!Enum.IsDefined (typeof (DataSetDateTime), value))
\r
170 throw new InvalidEnumArgumentException ("The DataSetDateTime enumeration value, " +
\r
171 (int)value + ", is invalid.");
\r
173 if (_datetimeMode == value)
\r
175 if (_table == null || _table.Rows.Count == 0) {
\r
176 _datetimeMode = value;
\r
179 if ((_datetimeMode == DataSetDateTime.Unspecified || _datetimeMode == DataSetDateTime.UnspecifiedLocal)
\r
180 && (value == DataSetDateTime.Unspecified || value == DataSetDateTime.UnspecifiedLocal)) {
\r
181 _datetimeMode = value;
\r
185 throw new InvalidOperationException ( String.Format (
\r
186 "Cannot change DateTimeMode from '{0}' to '{1}' " +
\r
187 "once the table has data.",_datetimeMode, value));
\r
192 [DataCategory ("Data")]
\r
194 [DataSysDescription ("Indicates whether null values are allowed in this column.")]
\r
196 [DefaultValue (true)]
\r
197 public bool AllowDBNull
\r
200 return _allowDBNull;
\r
203 //TODO: If we are a part of the table and this value changes
\r
204 //we need to validate that all the existing values conform to the new setting
\r
208 _allowDBNull = true;
\r
212 //if Value == false case
\r
213 if (null != _table)
\r
215 if (_table.Rows.Count > 0)
\r
217 bool nullsFound = false;
\r
218 for(int r = 0; r < _table.Rows.Count; r++) {
\r
219 DataRow row = _table.Rows[r];
\r
220 DataRowVersion version = row.HasVersion (DataRowVersion.Default) ?
\r
221 DataRowVersion.Default : DataRowVersion.Original;
\r
222 if(row.IsNull(this, version)) {
\r
229 throw new DataException("Column '" + ColumnName + "' has null values in it.");
\r
230 //TODO: Validate no null values exist
\r
231 //do we also check different versions of the row??
\r
235 _allowDBNull = value;
\r
240 /// Gets or sets a value indicating whether the column automatically increments the value of the column for new rows added to the table.
\r
243 /// If the type of this column is not Int16, Int32, or Int64 when this property is set,
\r
244 /// the DataType property is coerced to Int32. An exception is generated if this is a computed column
\r
245 /// (that is, the Expression property is set.) The incremented value is used only if the row's value for this column,
\r
246 /// when added to the columns collection, is equal to the default value.
\r
248 [DataCategory ("Data")]
\r
250 [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
252 [DefaultValue (false)]
\r
253 [RefreshProperties (RefreshProperties.All)]
\r
254 public bool AutoIncrement
\r
257 return _autoIncrement;
\r
262 //Can't be true if this is a computed column
\r
263 if (Expression != string.Empty)
\r
265 throw new ArgumentException("Can not Auto Increment a computed column.");
\r
268 if ( DefaultValue != DBNull.Value ) {
\r
269 throw new ArgumentException("Can not set AutoIncrement while" +
\r
270 " default value exists for this column.");
\r
273 if(!CanAutoIncrement(DataType))
\r
275 DataType = typeof(Int32);
\r
278 if (_table != null)
\r
279 _table.Columns.UpdateAutoIncrement(this,true);
\r
283 if (_table != null)
\r
284 _table.Columns.UpdateAutoIncrement(this,false);
\r
286 _autoIncrement = value;
\r
290 [DataCategory ("Data")]
\r
292 [DataSysDescription ("Indicates the starting value for an AutoIncrement column.")]
\r
295 public long AutoIncrementSeed
\r
298 return _autoIncrementSeed;
\r
301 _autoIncrementSeed = value;
\r
302 _nextAutoIncrementValue = _autoIncrementSeed;
\r
306 [DataCategory ("Data")]
\r
308 [DataSysDescription ("Indicates the increment used by an AutoIncrement column.")]
\r
311 public long AutoIncrementStep
\r
314 return _autoIncrementStep;
\r
317 _autoIncrementStep = value;
\r
321 internal void UpdateAutoIncrementValue(long value64)
\r
323 if (_autoIncrementStep > 0 ) {
\r
324 if (value64 >= _nextAutoIncrementValue) {
\r
325 _nextAutoIncrementValue = value64;
\r
326 AutoIncrementValue ();
\r
329 else if (value64 <= _nextAutoIncrementValue) {
\r
330 AutoIncrementValue ();
\r
334 internal long AutoIncrementValue ()
\r
336 long currentValue = _nextAutoIncrementValue;
\r
337 _nextAutoIncrementValue += AutoIncrementStep;
\r
338 return currentValue;
\r
341 internal long GetAutoIncrementValue ()
\r
343 return _nextAutoIncrementValue;
\r
346 internal void SetDefaultValue(int index) {
\r
348 this[index] = _nextAutoIncrementValue;
\r
350 DataContainer.CopyValue(Table.DefaultValuesRowIndex, index);
\r
353 [DataCategory ("Data")]
\r
355 [DataSysDescription ("Indicates the default user-interface caption for this column.")]
\r
357 public string Caption
\r
360 if(_caption == null)
\r
367 value = String.Empty;
\r
374 [DataSysDescription ("Indicates how this column persists in XML: as an attribute, element, simple content node, or nothing.")]
\r
376 [DefaultValue (MappingType.Element)]
\r
377 public virtual MappingType ColumnMapping
\r
380 return _columnMapping;
\r
383 _columnMapping = value;
\r
387 [DataCategory ("Data")]
\r
389 [DataSysDescription ("Indicates the name used to look up this column in the Columns collection of a DataTable.")]
\r
391 [RefreshProperties (RefreshProperties.All)]
\r
392 [DefaultValue ("")]
\r
393 public string ColumnName
\r
396 return _columnName;
\r
400 value = String.Empty;
\r
402 CultureInfo info = Table != null ? Table.Locale : CultureInfo.CurrentCulture;
\r
403 if (String.Compare(value, _columnName, true, info) != 0) {
\r
404 if (Table != null) {
\r
405 if (value.Length == 0)
\r
406 throw new ArgumentException("ColumnName is required when it is part of a DataTable.");
\r
408 Table.Columns.RegisterName(value, this);
\r
409 if (_columnName.Length > 0)
\r
410 Table.Columns.UnregisterName(_columnName);
\r
413 RaisePropertyChanging("ColumnName");
\r
414 _columnName = value;
\r
417 Table.ResetPropertyDescriptorsCache();
\r
419 else if (String.Compare(value, _columnName, false, info) != 0) {
\r
420 RaisePropertyChanging("ColumnName");
\r
421 _columnName = value;
\r
424 Table.ResetPropertyDescriptorsCache();
\r
429 [DataCategory ("Data")]
\r
431 [DataSysDescription ("Indicates the type of data stored in this column.")]
\r
433 [DefaultValue (typeof (string))]
\r
434 [RefreshProperties (RefreshProperties.All)]
\r
435 [TypeConverterAttribute (typeof (ColumnTypeConverter))]
\r
436 public Type DataType
\r
439 return DataContainer.Type;
\r
443 if ( value == null )
\r
446 if ( _dataContainer != null ) {
\r
447 if ( value == _dataContainer.Type )
\r
450 // check if data already exists can we change the datatype
\r
451 if ( _dataContainer.Capacity > 0 )
\r
452 throw new ArgumentException("The column already has data stored.");
\r
455 if (null != GetParentRelation () || null != GetChildRelation ())
\r
456 throw new InvalidConstraintException ("Cannot change datatype, " +
\r
457 "when column is part of a relation");
\r
460 if (_dataContainer != null && _dataContainer.Type == typeof (DateTime))
\r
461 _datetimeMode = DataSetDateTime.UnspecifiedLocal;
\r
463 _dataContainer = AbstractDataContainer.CreateInstance(value, this);
\r
465 //Check AutoIncrement status, make compatible datatype
\r
466 if(AutoIncrement == true) {
\r
467 // we want to check that the datatype is supported?
\r
468 TypeCode typeCode = Type.GetTypeCode(value);
\r
470 if(typeCode != TypeCode.Int16 &&
\r
471 typeCode != TypeCode.Int32 &&
\r
472 typeCode != TypeCode.Int64) {
\r
473 AutoIncrement = false;
\r
482 /// <remarks>When AutoIncrement is set to true, there can be no default value.</remarks>
\r
483 /// <exception cref="System.InvalidCastException"></exception>
\r
484 /// <exception cref="System.ArgumentException"></exception>
\r
485 [DataCategory ("Data")]
\r
487 [DataSysDescription ("Indicates the default column value used when adding new rows to the table.")]
\r
489 [TypeConverterAttribute (typeof (System.Data.DefaultValueTypeConverter))]
\r
490 public object DefaultValue
\r
493 return _defaultValue;
\r
497 if (AutoIncrement) {
\r
498 throw new ArgumentException("Can not set default value while" +
\r
499 " AutoIncrement is true on this column.");
\r
503 if (!this._defaultValue.Equals(value)) {
\r
504 if (value == null) {
\r
505 tmpObj = DBNull.Value;
\r
511 if ((this.DataType != typeof (object))&& (tmpObj != DBNull.Value)) {
\r
513 //Casting to the new type
\r
514 tmpObj= Convert.ChangeType(tmpObj,this.DataType);
\r
516 catch (InvalidCastException) {
\r
517 throw new InvalidCastException("Default Value type is not compatible with" +
\r
521 _defaultValue = tmpObj;
\r
524 // store default value in the table if already belongs to
\r
525 if (Table != null && Table.DefaultValuesRowIndex != -1) {
\r
526 DataContainer[Table.DefaultValuesRowIndex] = _defaultValue;
\r
531 [DataCategory ("Data")]
\r
533 [DataSysDescription ("Indicates the value that this column computes for each row based on other columns instead of taking user input.")]
\r
535 [DefaultValue ("")]
\r
536 [RefreshProperties (RefreshProperties.All)]
\r
537 public string Expression
\r
540 return _expression;
\r
544 value = String.Empty;
\r
546 if (value != String.Empty)
\r
549 if (AutoIncrement || Unique)
\r
550 throw new ArgumentException("Cannot create an expression on a column that has AutoIncrement or Unique.");
\r
554 for (int i = 0; i < Table.Constraints.Count; i++)
\r
556 if (Table.Constraints[i].IsColumnContained(this))
\r
557 throw new ArgumentException(String.Format("Cannot set Expression property on column {0}, because it is a part of a constraint.", ColumnName));
\r
561 Parser parser = new Parser ();
\r
562 IExpression compiledExpression = parser.Compile (value);
\r
566 if (compiledExpression.DependsOn(this))
\r
567 throw new ArgumentException("Cannot set Expression property due to circular reference in the expression.");
\r
568 // Check if expression is ok
\r
569 if (Table.Rows.Count == 0)
\r
570 compiledExpression.Eval (Table.NewRow());
\r
572 compiledExpression.Eval (Table.Rows[0]);
\r
575 _compiledExpression = compiledExpression;
\r
579 _compiledExpression = null;
\r
580 if (Table != null) {
\r
581 int defaultValuesRowIndex = Table.DefaultValuesRowIndex;
\r
582 if ( defaultValuesRowIndex != -1)
\r
583 DataContainer.FillValues(defaultValuesRowIndex);
\r
586 _expression = value;
\r
590 internal IExpression CompiledExpression {
\r
591 get { return _compiledExpression; }
\r
594 [Browsable (false)]
\r
595 [DataCategory ("Data")]
\r
597 [DataSysDescription ("The collection that holds custom user information.")]
\r
599 public PropertyCollection ExtendedProperties
\r
602 return _extendedProperties;
\r
605 internal set { _extendedProperties = value; }
\r
609 [DataCategory ("Data")]
\r
611 [DataSysDescription ("Indicates the maximum length of the value this column allows. ")]
\r
613 [DefaultValue (-1)]
\r
614 public int MaxLength
\r
617 //Default == -1 no max length
\r
622 _columnMapping == MappingType.SimpleContent)
\r
623 throw new ArgumentException (String.Format ("Cannot set MaxLength property on '{0}' column which is mapped to SimpleContent.", ColumnName));
\r
624 //only applies to string columns
\r
625 _maxLength = value;
\r
629 [DataCategory ("Data")]
\r
631 [DataSysDescription ("Indicates the XML uri for elements or attributes stored in this column.")]
\r
633 public string Namespace
\r
636 if (_nameSpace != null)
\r
640 if ((Table != null) && (_columnMapping != MappingType.Attribute))
\r
642 return Table.Namespace;
\r
644 return String.Empty;
\r
647 _nameSpace = value;
\r
651 //Need a good way to set the Ordinal when the column is added to a columnCollection.
\r
652 [Browsable (false)]
\r
653 [DataCategory ("Data")]
\r
655 [DataSysDescription ("Indicates the index of this column in the Columns collection.")]
\r
657 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
\r
658 public int Ordinal {
\r
659 get { return _ordinal; }
\r
661 internal set { _ordinal = value; }
\r
666 public void SetOrdinal (int ordinal)
\r
668 if (_ordinal == -1)
\r
669 throw new ArgumentException ("Column must belong to a table.");
\r
670 _table.Columns.MoveColumn (_ordinal, ordinal);
\r
671 _ordinal = ordinal;
\r
674 internal void SetOrdinal(int ordinal)
\r
676 _ordinal = ordinal;
\r
680 [DataCategory ("Data")]
\r
682 [DataSysDescription ("Indicates the Prefix used for this DataColumn in xml representation.")]
\r
684 [DefaultValue ("")]
\r
685 public string Prefix
\r
692 value = String.Empty;
\r
697 [DataCategory ("Data")]
\r
699 [DataSysDescription ("Indicates whether this column allows changes once a row has been added to the table.")]
\r
701 [DefaultValue (false)]
\r
702 public bool ReadOnly
\r
712 [Browsable (false)]
\r
713 [DataCategory ("Data")]
\r
715 [DataSysDescription ("Returns the DataTable to which this column belongs.")]
\r
717 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
\r
718 public DataTable Table
\r
725 [DataCategory ("Data")]
\r
727 [DataSysDescription ("Indicates whether this column should restrict its values in the rows of the table to be unique.")]
\r
729 [DefaultValue (false)]
\r
730 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
\r
731 public bool Unique
\r
738 if (_unique == value)
\r
741 // Set the property value, so that when adding/removing the constraint
\r
742 // we dont run into recursive issues.
\r
745 if (_table == null)
\r
750 if (Expression != null && Expression != String.Empty)
\r
751 throw new ArgumentException("Cannot change Unique property for the expression column.");
\r
753 _table.Constraints.Add(null, this, false);
\r
756 UniqueConstraint uc = UniqueConstraint.GetUniqueConstraintForColumnSet (_table.Constraints,
\r
757 new DataColumn[] {this});
\r
758 _table.Constraints.Remove (uc);
\r
760 } catch (Exception e) {
\r
767 internal AbstractDataContainer DataContainer {
\r
769 return _dataContainer;
\r
773 internal static bool CanAutoIncrement(Type type) {
\r
774 switch (Type.GetTypeCode(type)) {
\r
775 case TypeCode.Int16:
\r
776 case TypeCode.Int32:
\r
777 case TypeCode.Int64:
\r
778 case TypeCode.Decimal:
\r
785 #endregion // Properties
\r
791 protected internal void CheckNotAllowNull() {
\r
795 protected void CheckUnique() {
\r
799 internal DataColumn Clone() {
\r
800 DataColumn copy = new DataColumn ();
\r
802 // Copy all the properties of column
\r
803 copy._allowDBNull = _allowDBNull;
\r
804 copy._autoIncrement = _autoIncrement;
\r
805 copy._autoIncrementSeed = _autoIncrementSeed;
\r
806 copy._autoIncrementStep = _autoIncrementStep;
\r
807 copy._caption = _caption;
\r
808 copy._columnMapping = _columnMapping;
\r
809 copy._columnName = _columnName;
\r
811 copy.DataType = DataType;
\r
812 copy._defaultValue = _defaultValue;
\r
813 copy._expression = _expression;
\r
814 //Copy.ExtendedProperties
\r
815 copy._maxLength = _maxLength;
\r
816 copy._nameSpace = _nameSpace;
\r
817 copy._prefix = _prefix;
\r
818 copy._readOnly = _readOnly;
\r
820 //we do not copy the unique value - it will be copyied when copying the constraints.
\r
821 //Copy.Unique = Column.Unique;
\r
823 if (DataType == typeof (DateTime))
\r
824 copy.DateTimeMode = _datetimeMode;
\r
831 /// Sets unique true whithout creating Constraint
\r
833 internal void SetUnique()
\r
839 internal void AssertCanAddToCollection()
\r
841 //Check if Default Value is set and AutoInc is set
\r
845 protected internal void CheckNotAllowNull ()
\r
847 throw new NotImplementedException ();
\r
851 protected void CheckUnique ()
\r
853 throw new NotImplementedException ();
\r
856 protected internal virtual void
\r
857 OnPropertyChanging (PropertyChangedEventArgs pcevent) {
\r
858 if (PropertyChanged != null)
\r
859 PropertyChanged (this, pcevent);
\r
862 protected internal void RaisePropertyChanging(string name) {
\r
863 PropertyChangedEventArgs e = new PropertyChangedEventArgs (name);
\r
864 OnPropertyChanging (e);
\r
868 /// Gets the Expression of the column, if one exists.
\r
870 /// <returns>The Expression value, if the property is set;
\r
871 /// otherwise, the ColumnName property.</returns>
\r
872 public override string ToString()
\r
874 if (_expression != string.Empty)
\r
875 return ColumnName + " + " + _expression;
\r
880 internal void SetTable(DataTable table) {
\r
881 if(_table!=null) { // serves as double check while adding to a table
\r
882 throw new ArgumentException("The column already belongs to a different table");
\r
885 // this will get called by DataTable
\r
886 // and DataColumnCollection
\r
888 // if the DataColumn is marked as Unique and then
\r
889 // added to a DataTable , then a UniqueConstraint
\r
890 // should be created
\r
891 UniqueConstraint uc = new UniqueConstraint(this);
\r
892 _table.Constraints.Add(uc);
\r
895 // allocate space in the column data container
\r
896 DataContainer.Capacity = _table.RecordCache.CurrentCapacity;
\r
898 int defaultValuesRowIndex = _table.DefaultValuesRowIndex;
\r
899 if ( defaultValuesRowIndex != -1) {
\r
900 // store default value in the table
\r
901 DataContainer[defaultValuesRowIndex] = _defaultValue;
\r
902 // Set all the values in data container to default
\r
903 // it's cheaper that raise event on each row.
\r
904 DataContainer.FillValues(defaultValuesRowIndex);
\r
908 // Returns true if all the same collumns are in columnSet and compareSet
\r
909 internal static bool AreColumnSetsTheSame(DataColumn[] columnSet, DataColumn[] compareSet)
\r
911 if (null == columnSet && null == compareSet) {
\r
915 if (null == columnSet || null == compareSet) {
\r
919 if (columnSet.Length != compareSet.Length) {
\r
923 foreach (DataColumn col in columnSet) {
\r
924 bool matchFound = false;
\r
925 foreach (DataColumn compare in compareSet) {
\r
926 if (col == compare) {
\r
927 matchFound = true;
\r
930 if (! matchFound) {
\r
938 internal int CompareValues (int index1, int index2)
\r
940 return DataContainer.CompareValues(index1, index2);
\r
944 /// Returns the data relation, which contains this column.
\r
945 /// This searches in current table's parent relations.
\r
948 /// DataRelation if found otherwise null.
\r
950 private DataRelation GetParentRelation ()
\r
952 if (_table == null)
\r
954 foreach (DataRelation rel in _table.ParentRelations)
\r
955 if (rel.Contains (this))
\r
962 /// Returns the data relation, which contains this column.
\r
963 /// This searches in current table's child relations.
\r
966 /// DataRelation if found otherwise null.
\r
968 private DataRelation GetChildRelation ()
\r
970 if (_table == null)
\r
972 foreach (DataRelation rel in _table.ChildRelations)
\r
973 if (rel.Contains (this))
\r
978 internal void ResetColumnInfo ()
\r
982 if (_compiledExpression != null)
\r
983 _compiledExpression.ResetExpression ();
\r
986 internal bool DataTypeMatches (DataColumn col)
\r
988 if (DataType != col.DataType)
\r
991 if (DataType != typeof (DateTime))
\r
994 if (DateTimeMode == col.DateTimeMode)
\r
997 if (DateTimeMode == DataSetDateTime.Local || DateTimeMode == DataSetDateTime.Utc)
\r
1000 if (col.DateTimeMode == DataSetDateTime.Local || col.DateTimeMode == DataSetDateTime.Utc)
\r
1005 #endregion // Methods
\r