2 // System.Data.DataColumn.cs
5 // Franklin Wise (gracenote@earthlink.net)
6 // Christopher Podurgiel (cpodurgiel@msn.com)
7 // Rodrigo Moya (rodrigo@ximian.com)
8 // Daniel Morgan (danmorg@sc.rr.com)
10 // (C) Copyright 2002, Franklin Wise
11 // (C) Chris Podurgiel
12 // (C) Ximian, Inc 2002
17 using System.ComponentModel;
21 internal delegate void DelegateColumnValueChange(DataColumn column,
22 DataRow row, object proposedValue);
26 /// Summary description for DataColumn.
28 public class DataColumn : MarshalByValueComponent
32 //used for constraint validation
33 //if an exception is fired during this event the change should be canceled
34 internal event DelegateColumnValueChange ValidateColumnValueChange;
36 //used for FK Constraint Cascading rules
37 internal event DelegateColumnValueChange ColumnValueChanging;
43 private bool _allowDBNull = true;
44 private bool _autoIncrement = false;
45 private long _autoIncrementSeed = 0;
46 private long _autoIncrementStep = 1;
47 private string _caption = null;
48 private MappingType _columnMapping = MappingType.Element;
49 private string _columnName = null;
50 private Type _dataType = null;
51 private object _defaultValue = null;
52 private string expression = null;
53 private PropertyCollection _extendedProperties = null;
54 private int maxLength = -1; //-1 represents no length limit
55 private string nameSpace = null;
56 private int _ordinal = -1; //-1 represents not part of a collection
57 private string prefix = null;
58 private bool readOnly = false;
59 private DataTable _table = null;
60 private bool unique = false;
70 //TODO: Ctor init vars directly
71 public DataColumn(string columnName): this()
73 ColumnName = columnName;
76 public DataColumn(string columnName, Type dataType): this(columnName)
78 if(dataType == null) {
79 throw new ArgumentNullException("dataType can't be null.");
86 public DataColumn( string columnName, Type dataType,
87 string expr): this(columnName, dataType)
92 public DataColumn(string columnName, Type dataType,
93 string expr, MappingType type): this(columnName, dataType, expr)
101 public bool AllowDBNull
107 //TODO: If we are a part of the table and this value changes
108 //we need to validate that all the existing values conform to the new setting
116 //if Value == false case
119 if (_table.Rows.Count > 0)
121 //TODO: Validate no null values exist
122 //do we also check different versions of the row??
126 _allowDBNull = value;
131 /// Gets or sets a value indicating whether the column automatically increments the value of the column for new rows added to the table.
134 /// If the type of this column is not Int16, Int32, or Int64 when this property is set,
135 /// the DataType property is coerced to Int32. An exception is generated if this is a computed column
136 /// (that is, the Expression property is set.) The incremented value is used only if the row's value for this column,
137 /// when added to the columns collection, is equal to the default value.
139 public bool AutoIncrement
142 return _autoIncrement;
147 //Can't be true if this is a computed column
148 if(Expression != null)
150 throw new ArgumentException("Can't Auto Increment a computed column.");
153 //If the DataType of this Column isn't an Int
155 if(Type.GetTypeCode(_dataType) != TypeCode.Int16 &&
156 Type.GetTypeCode(_dataType) != TypeCode.Int32 &&
157 Type.GetTypeCode(_dataType) != TypeCode.Int64)
159 _dataType = typeof(Int32);
162 _autoIncrement = value;
166 public long AutoIncrementSeed
169 return _autoIncrementSeed;
172 _autoIncrementSeed = value;
176 public long AutoIncrementStep
179 return _autoIncrementStep;
182 _autoIncrementStep = value;
186 public string Caption
199 public virtual MappingType ColumnMapping
202 return _columnMapping;
205 _columnMapping = value;
209 public string ColumnName
212 return "" + _columnName;
215 //Both are checked after the column is part of the collection
216 //TODO: Check Name duplicate
217 //TODO: check Name != null
228 //TODO: check if data already exists can we change the datatype
230 //TODO: we want to check that the datatype is supported?
232 //Check AutoIncrement status, make compatible datatype
233 //TODO: Check for other int values i.e. Int16 etc
234 if(AutoIncrement == true &&
235 Type.GetTypeCode(value) != TypeCode.Int32)
237 throw new Exception(); //TODO: correction exception type
246 /// <remarks>When AutoIncrement is set to true, there can be no default value.</remarks>
247 /// <exception cref="System.InvalidCastException"></exception>
248 /// <exception cref="System.ArgumentException"></exception>
249 public object DefaultValue
252 return _defaultValue;
256 //If autoIncrement == true throw
259 throw new ArgumentException("Can not set default value while" +
260 " AutoIncrement is true on this column.");
263 //Will throw invalid cast exception
264 //if value is not the correct type
265 //FIXME: some types can be casted
266 if (value.GetType() != _dataType)
268 throw new InvalidCastException("Default Value type is not compatible with" +
272 _defaultValue = value;
277 public string Expression
283 //TODO: validation of the expression
284 expression = value; //Check?
288 public PropertyCollection ExtendedProperties
291 return _extendedProperties;
298 //Default == -1 no max length
302 //only applies to string columns
307 public string Namespace
317 //Need a good way to set the Ordinal when the column is added to a columnCollection.
321 //value is -1 if not part of a collection
326 internal void SetOrdinal(int ordinal)
351 public DataTable Table
365 //if Table == null then the UniqueConstraint is
366 //created on addition to the collection
368 //FIXME?: need to check if value is the same
369 //because when calling "new UniqueConstraint"
370 //the new object tries to set "column.Unique = True"
371 //which creates an infinite loop.
380 UniqueConstraint uc = new UniqueConstraint(this);
381 _table.Constraints.Add(uc);
388 //FIXME: Add code to remove constraint from DataTable
389 throw new NotImplementedException ();
397 #endregion // Properties
403 protected internal void CheckNotAllowNull() {
407 protected void CheckUnique() {
412 internal void AssertCanAddToCollection()
414 //Check if Default Value is set and AutoInc is set
418 protected internal virtual void
419 OnPropertyChanging (PropertyChangedEventArgs pcevent) {
423 protected internal void RaisePropertyChanging(string name) {
427 /// Gets the Expression of the column, if one exists.
429 /// <returns>The Expression value, if the property is set;
430 /// otherwise, the ColumnName property.</returns>
432 public override string ToString()
434 if (expression != null)
441 internal void SetTable(DataTable table) {
443 // this will get called by DataTable
444 // and DataColumnCollection
448 // Returns true if all the same collumns are in columnSet and compareSet
449 internal static bool AreColumnSetsTheSame(DataColumn[] columnSet, DataColumn[] compareSet)
451 if (null == columnSet && null == compareSet) return true;
452 if (null == columnSet || null == compareSet) return false;
454 if (columnSet.Length != compareSet.Length) return false;
456 foreach (DataColumn col in columnSet)
458 bool matchFound = false;
459 foreach (DataColumn compare in compareSet)
466 if (! matchFound) return false;
472 #endregion // Methods