DataColumn.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ Dotnetfx_Win7_3.5.1 / Dotnetfx_Win7_3.5.1 / 3.5.1 / DEVDIV / depot / DevDiv / releases / whidbey / NetFXspW7 / ndp / fx / src / Data / System / Data / DataColumn.cs / 1 / DataColumn.cs

                            //------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// [....] 
// [....]
//----------------------------------------------------------------------------- 
 
namespace System.Data {
    using System; 
    using System.Xml;
    using System.Data.Common;
    using System.ComponentModel;
    using System.Diagnostics; 
    using System.Collections;
    using System.Globalization; 
    using System.Data.SqlTypes; 
    using System.Xml.Serialization;
    using System.Collections.Generic; 

    /// 
    ///    
    ///       Represents one column of data in a . 
    ///    
    ///  
    [ 
    ToolboxItem(false),
    DesignTimeVisible(false), 
    DefaultProperty("ColumnName"),
    Editor("Microsoft.VSDesigner.Data.Design.DataColumnEditor, " + AssemblyRef.MicrosoftVSDesigner, "System.Drawing.Design.UITypeEditor, " + AssemblyRef.SystemDrawing),
    ]
#if WINFSInternalOnly 
    internal
#else 
    public 
#endif
    class DataColumn : MarshalByValueComponent { 

        // properties
        private bool allowNull              = true;
        private bool autoIncrement          = false; 
        private Int64 autoIncrementStep       = 1;
        private Int64 autoIncrementSeed       = 0; 
        private string caption              = null; 
        private string _columnName          = null;
        private Type dataType               = null; 
        internal object defaultValue        = DBNull.Value;             // DefaultValue Converter
        private DataSetDateTime _dateTimeMode  =  DataSetDateTime.UnspecifiedLocal;
        private DataExpression expression   = null;
        private int maxLength             = -1; 
        private int _ordinal                = -1;
        private bool readOnly               = false; 
        internal Index sortIndex            = null; 
        internal DataTable table            = null;
        private bool unique                 = false; 
        internal MappingType columnMapping  = MappingType.Element;
        internal int _hashCode;

        internal int errors; 
        private bool isSqlType = false;
        private bool implementsINullable = false; 
        private bool implementsIChangeTracking = false; 
        private bool implementsIRevertibleChangeTracking = false;
        private bool implementsIXMLSerializable = false; 

        private bool defaultValueIsNull = true;

        // list of columns whose expression consume values from this column 
        internal List dependentColumns = null;
 
        // collections 
        internal PropertyCollection extendedProperties = null;
 
        // events
        private PropertyChangedEventHandler onPropertyChangingDelegate = null;

        // state 
        private DataStorage _storage;
        internal Int64 autoIncrementCurrent = 0; 
 
        //
        // The _columnClass member is the class for the unfoliated virtual nodes in the XML. 
        //
        internal string _columnUri        = null;
        private string _columnPrefix     = "";
        internal string encodedColumnName  = null; 

        // XML-specific Column Properties 
        internal string description = ""; 

        // 
        internal string dttype = "";        // The type specified in dt:type attribute
        internal SimpleType simpleType = null;

        private static int _objectTypeCount; // Bid counter 
        private readonly int _objectID = System.Threading.Interlocked.Increment(ref _objectTypeCount);
 
        ///  
        ///    
        ///       Initializes a new instance of a  
        ///       class.
        ///    
        /// 
        public DataColumn() : this(null, typeof(string), null, MappingType.Element) { 
        }
 
        ///  
        ///    
        ///       Inititalizes a new instance of the  class 
        ///       using the specified column name.
        ///    
        /// 
        public DataColumn(string columnName) : this(columnName, typeof(string), null, MappingType.Element) { 
        }
 
        ///  
        ///    
        ///       Inititalizes a new instance of the  class 
        ///       using the specified column name and data type.
        ///    
        /// 
        public DataColumn(string columnName, Type dataType) : this(columnName, dataType, null, MappingType.Element) { 
        }
 
        ///  
        ///    
        ///       Initializes a new instance 
        ///       of the  class
        ///       using the specified name, data type, and expression.
        ///    
        ///  
        public DataColumn(string columnName, Type dataType, string expr) : this(columnName, dataType, expr, MappingType.Element) {
        } 
 
        /// 
        ///     
        ///       Initializes a new instance of the  class
        ///       using
        ///       the specified name, data type, expression, and value that determines whether the
        ///       column is an attribute. 
        ///    
        ///  
        public DataColumn(string columnName, Type dataType, string expr, MappingType type) { 
            GC.SuppressFinalize(this);
            Bid.Trace(" %d#, columnName='%ls', expr='%ls', type=%d{ds.MappingType}\n", 
                          ObjectID, columnName, expr, (int)type);

            if (dataType == null) {
                throw ExceptionBuilder.ArgumentNull("dataType"); 
            }
 
            StorageType typeCode = DataStorage.GetStorageType(dataType); 
            if (DataStorage.ImplementsINullableValue(typeCode, dataType)) {
                throw ExceptionBuilder.ColumnTypeNotSupported(); 
            }
            _columnName = (columnName == null ? "" : columnName);

            SimpleType stype = SimpleType.CreateSimpleType(dataType); 
            if (null != stype) {
                this.SimpleType = stype; 
            } 
            UpdateColumnType(dataType, typeCode);
 
            if ((null != expr) && (0 < expr.Length)) {
                // @perfnote: its a performance hit to set Expression to the empty str when we know it will come out null
                this.Expression = expr;
            } 
            this.columnMapping = type;
        } 
 

        private void UpdateColumnType(Type type, StorageType typeCode) { 
            this.dataType = type;
            if (StorageType.DateTime != typeCode) { // revert _dateTimeMode back to default, when column type is changed
                _dateTimeMode =  DataSetDateTime.UnspecifiedLocal;
            } 
            DataStorage.ImplementsInterfaces(
                                typeCode, type, 
                                out isSqlType, 
                                out implementsINullable,
                                out implementsIXMLSerializable, 
                                out implementsIChangeTracking,
                                out implementsIRevertibleChangeTracking);

            if (!isSqlType && implementsINullable) { 
                SqlUdtStorage.GetStaticNullForUdtType(type);
            } 
        } 

        // PUBLIC PROPERTIES 

        /// 
        ///    
        ///       Gets or sets a value indicating whether null 
        ///       values are
        ///       allowed in this column for rows belonging to the table. 
        ///     
        /// 
        [ 
        ResCategoryAttribute(Res.DataCategory_Data),
        DefaultValue(true),
        ResDescriptionAttribute(Res.DataColumnAllowNullDescr)
        ] 
        public bool AllowDBNull {
            get { 
                return allowNull; 
            }
            set { 
                IntPtr hscp;
                Bid.ScopeEnter(out hscp, " %d#, %d{bool}\n", ObjectID, value);
                try {
                    if (allowNull != value) { 
                        if (table != null) {
                            if (!value && table.EnforceConstraints) 
                                CheckNotAllowNull(); 
                        }
                        this.allowNull = value; 
                    }
                    //
                }
                finally { 
                    Bid.ScopeLeave(ref hscp);
                } 
            } 
        }
 
        /// 
        ///    
        ///       Gets or
        ///       sets a value indicating whether the column automatically increments the value of the column for new 
        ///       rows added to the table.
        ///     
        ///  
        [
        ResCategoryAttribute(Res.DataCategory_Data), 
        RefreshProperties(RefreshProperties.All),
        DefaultValue(false),
        ResDescriptionAttribute(Res.DataColumnAutoIncrementDescr)
        ] 
        public bool AutoIncrement {
            get { 
                return autoIncrement; 
            }
            set { 
                Bid.Trace(" %d#, %d{bool}\n", ObjectID, value);
                if (autoIncrement != value) {
                    if (value) {
                        if (expression != null) { 
                            throw ExceptionBuilder.AutoIncrementAndExpression();
                        } 
//                        if (defaultValue != null && defaultValue != DBNull.Value) { 
                        if (!DefaultValueIsNull){
                            throw ExceptionBuilder.AutoIncrementAndDefaultValue(); 
                        }
                        if (!IsAutoIncrementType(DataType)) {
                            if (HasData) {
                                throw ExceptionBuilder.AutoIncrementCannotSetIfHasData(DataType.Name); 
                            }
                            DataType = typeof(int); 
                        } 
                    }
                    autoIncrement = value; 
                }
            }
        }
 
        /// 
        ///     
        ///       Gets 
        ///       or sets the starting value for a column that has its
        ///     property 
        ///       set to 
        ///       .
        ///    
        ///  
        [
        ResCategoryAttribute(Res.DataCategory_Data), 
        DefaultValue((Int64)0), 
        ResDescriptionAttribute(Res.DataColumnAutoIncrementSeedDescr)
        ] 
        public Int64 AutoIncrementSeed {
            get {
                return autoIncrementSeed;
            } 
            set {
                Bid.Trace(" %d#, %I64d\n", ObjectID, value); 
                if (autoIncrementSeed != value) { 
                    if (autoIncrementCurrent == autoIncrementSeed) {
                        autoIncrementCurrent = value; 
                    }

                    if (AutoIncrementStep > 0) {
                        if (autoIncrementCurrent < value) { 
                            autoIncrementCurrent = value;
                        } 
                    } 
                    else {
                        if (autoIncrementCurrent > value) { 
                            autoIncrementCurrent = value;
                        }
                    }
 
                    autoIncrementSeed = value;
                } 
            } 
        }
 
        /// 
        ///    
        ///       Gets or sets the increment used by a column with its 
        ///       property set to  
        ///       .
        ///     
        ///  
        [
        ResCategoryAttribute(Res.DataCategory_Data), 
        DefaultValue((Int64)1),
        ResDescriptionAttribute(Res.DataColumnAutoIncrementStepDescr)
        ]
        public Int64 AutoIncrementStep { 
            get {
                return autoIncrementStep; 
            } 
            set {
                Bid.Trace(" %d#, %I64d\n", ObjectID, value); 
                if (autoIncrementStep != value) {
                    if (value == 0)
                        throw ExceptionBuilder.AutoIncrementSeed();
                    if (autoIncrementCurrent != autoIncrementSeed) 
                        autoIncrementCurrent += (value - autoIncrementStep);
                    autoIncrementStep = value; 
                } 
            }
        } 

        /// 
        ///    
        ///       Gets or sets 
        ///       the caption for this column.
        ///     
        ///  
        [
        ResCategoryAttribute(Res.DataCategory_Data), 
        ResDescriptionAttribute(Res.DataColumnCaptionDescr)
        ]
        public string Caption {
            get { 
                return(caption != null) ? caption : _columnName;
            } 
            set { 
                if (value == null)
                    value = ""; 

                if (caption == null || String.Compare(caption, value, true, Locale) != 0) {
                    caption = value;
                } 
            }
        } 
 
        /// 
        ///     
        ///       Resets the  property to its previous value, or
        ///       to  .
        ///    
        ///  
        private void ResetCaption() {
            if (caption != null) { 
                caption = null; 
            }
        } 

        /// 
        ///    
        ///       Gets a value indicating whether the  has been explicitly set. 
        ///    
        ///  
        private bool ShouldSerializeCaption() { 
            return(caption != null);
        } 

        /// 
        ///    
        ///       Gets or sets the name of the column within the . 
        ///    
        ///  
        [ 
        RefreshProperties(RefreshProperties.All),
        ResCategoryAttribute(Res.DataCategory_Data), 
        DefaultValue(""),
        ResDescriptionAttribute(Res.DataColumnColumnNameDescr)
        ]
        public string ColumnName { 
            get {
                return _columnName; 
            } 
            set {
                IntPtr hscp; 
                Bid.ScopeEnter(out hscp, " %d#, '%ls'\n", ObjectID, value);
                try {
                    if (value == null) {
                        value = ""; 
                    }
 
                    if (String.Compare(_columnName, value, true, Locale) != 0) { 
                        if (table != null) {
                            if (value.Length == 0) 
                                throw ExceptionBuilder.ColumnNameRequired();

                            table.Columns.RegisterColumnName(value, this, (DataTable)null);
                            if (_columnName.Length != 0) 
                                table.Columns.UnregisterName(_columnName);
                        } 
 
                        RaisePropertyChanging("ColumnName");
                        _columnName = value; 
                        encodedColumnName = null;
                        if (table != null) {
                            table.Columns.OnColumnPropertyChanged(new CollectionChangeEventArgs(CollectionChangeAction.Refresh, this));
                        } 
                    }
                    else if (_columnName != value) { 
                        RaisePropertyChanging("ColumnName"); 
                        _columnName = value;
                        encodedColumnName = null; 
                        if (table != null) {
                            table.Columns.OnColumnPropertyChanged(new CollectionChangeEventArgs(CollectionChangeAction.Refresh, this));
                        }
                    } 
                }
                finally{ 
                    Bid.ScopeLeave(ref hscp); 
                }
            } 
        }

        internal string EncodedColumnName {
            get { 
                if ( this.encodedColumnName == null ) {
                    this.encodedColumnName = XmlConvert.EncodeLocalName( this.ColumnName ); 
                } 
                Debug.Assert( this.encodedColumnName != null && this.encodedColumnName.Length != 0);
                return this.encodedColumnName; 
            }
        }

        internal IFormatProvider FormatProvider { 
            get {
                // used for formating/parsing not comparing 
                return ((null != table) ? table.FormatProvider : CultureInfo.CurrentCulture); 
            }
        } 

        internal CultureInfo Locale {
            get {
                // used for comparing not formating/parsing 
                return ((null != table) ? table.Locale : CultureInfo.CurrentCulture);
            } 
        } 

        internal int ObjectID { 
            get {
                return _objectID;
            }
        } 

        [ 
        ResCategoryAttribute(Res.DataCategory_Data), 
        DefaultValue(""),
        ResDescriptionAttribute(Res.DataColumnPrefixDescr) 
        ]
        public string Prefix {
            get { return _columnPrefix;}
            set { 
                if (value == null)
                    value = ""; 
                Bid.Trace(" %d#, '%ls'\n", ObjectID, value); 

                if ((XmlConvert.DecodeName(value) == value) &&  (XmlConvert.EncodeName(value) != value)) 
                    throw ExceptionBuilder.InvalidPrefix(value);

                _columnPrefix = value;
 
            }
        } 
 
        // Return the field value as a string. If the field value is NULL, then NULL is return.
        // If the column type is string and it's value is empty, then the empty string is returned. 
        // If the column type is not string, or the column type is string and the value is not empty string, then a non-empty string is returned
        // This method does not throw any formatting exceptions, since we can always format the field value to a string.
        internal string GetColumnValueAsString( DataRow row, DataRowVersion version ) {
 
            object objValue = this[row.GetRecordFromVersion(version)];
 
            if (DataStorage.IsObjectNull(objValue)) { 
                return null;
            } 

            string value = ConvertObjectToXml(objValue);
            Debug.Assert(value != null);
 
            return value;
        } 
 
        /// 
        /// Whether this column computes values. 
        /// 
        internal bool Computed {
            get {
                return(this.expression == null ? false : true); 
            }
        } 
 
        /// 
        /// The internal expression object that computes the values. 
        /// 
        internal DataExpression DataExpression {
            get {
                return this.expression; 
            }
        } 
 
        /// 
        ///     
        ///       The type
        ///       of data stored in thecolumn.
        ///    
        ///  
        [
        ResCategoryAttribute(Res.DataCategory_Data), 
        DefaultValue(typeof(string)), 
        RefreshProperties(RefreshProperties.All),
        TypeConverter(typeof(ColumnTypeConverter)), 
        ResDescriptionAttribute(Res.DataColumnDataTypeDescr)
        ]
        public Type DataType {
            get { 
                return dataType;
            } 
            set { 
                if (dataType != value) {
                    if (HasData) { 
                        throw ExceptionBuilder.CantChangeDataType();
                    }
                    if (value == null) {
                        throw ExceptionBuilder.NullDataType(); 
                    }
                    StorageType typeCode = DataStorage.GetStorageType(value); 
                    if (DataStorage.ImplementsINullableValue(typeCode, value)) { 
                        throw ExceptionBuilder.ColumnTypeNotSupported();
                    } 
                    if (table != null && IsInRelation()) {
                        throw ExceptionBuilder.ColumnsTypeMismatch();
                    }
 
                    // If the DefualtValue is different from the Column DataType, we will coerce the value to the DataType
                    if (!DefaultValueIsNull){ 
                        try { 
                          if (typeof(string) == value) {// since string types can be null in value! DO NOT REMOVE THIS
                                defaultValue = DefaultValue.ToString(); 
                          }
                          else if (typeof(SqlString) == value){// since string types can be null in value! DO NOT REMOVE THIS
                              defaultValue = SqlConvert.ConvertToSqlString(DefaultValue);
                          } 
                          else if (typeof(object) != value) {
                                DefaultValue = SqlConvert.ChangeType(DefaultValue, value, FormatProvider); 
                          } 
                        }
                        catch (InvalidCastException) { 
                            throw ExceptionBuilder.DefaultValueDataType(ColumnName, DefaultValue.GetType(), value);
                        }
                        catch (FormatException) {
                            throw ExceptionBuilder.DefaultValueDataType(ColumnName, DefaultValue.GetType(), value); 
                        }
                    } 
 
                    if (this.ColumnMapping == MappingType.SimpleContent)
                        if (value == typeof(Char)) 
                            throw ExceptionBuilder.CannotSetSimpleContentType(ColumnName, value);

                    SimpleType = SimpleType.CreateSimpleType(value);
                    if (StorageType.String == typeCode) { 
                        maxLength = -1;
                    } 
                    UpdateColumnType(value, typeCode); 
                    XmlDataType = null;
 
                    if (AutoIncrement && !IsAutoIncrementType(value)) {
                        AutoIncrement = false;
                    }
                } 
            }
        } 
 
        [
        ResCategoryAttribute(Res.DataCategory_Data), 
        DefaultValue(DataSetDateTime.UnspecifiedLocal),
        RefreshProperties(RefreshProperties.All),
        ResDescriptionAttribute(Res.DataColumnDateTimeModeDescr)
        ] 
        public DataSetDateTime DateTimeMode {
            get { 
                return _dateTimeMode; 
            }
            set { 
                if (_dateTimeMode != value) {
                    if (DataType != typeof(DateTime) && value != DataSetDateTime.UnspecifiedLocal) { //Check for column being DateTime. If the column is not DateTime make sure the value that is being is only the default[UnspecifiedLocal].
                        throw ExceptionBuilder.CannotSetDateTimeModeForNonDateTimeColumns();
                    } 
                    switch(value) {
                        case DataSetDateTime.Utc: 
                        case DataSetDateTime.Local: 
                            if (HasData) {
                                throw ExceptionBuilder.CantChangeDateTimeMode(_dateTimeMode, value); 
                            }
                            break;
                        case DataSetDateTime.Unspecified:
                        case DataSetDateTime.UnspecifiedLocal: 
                            if (_dateTimeMode == DataSetDateTime.Unspecified || _dateTimeMode == DataSetDateTime.UnspecifiedLocal) {
                                break; 
                            } 
                            if (HasData) {
                                throw ExceptionBuilder.CantChangeDateTimeMode(_dateTimeMode, value); 
                            }
                            break;
                        default :
                            throw ExceptionBuilder.InvalidDateTimeMode(value); 
                    }
                    _dateTimeMode = value; 
                } 
            }
        } 

        /// 
        ///    Gets or sets the default value for the
        ///       column when creating new rows. 
        /// 
        [ 
        ResCategoryAttribute(Res.DataCategory_Data), 
        ResDescriptionAttribute(Res.DataColumnDefaultValueDescr),
        TypeConverter(typeof(DefaultValueTypeConverter)) 
        ]
        public object DefaultValue {
            get {
                Debug.Assert(defaultValue != null, "It should not have been set to null."); 
                if (defaultValue == DBNull.Value && this.implementsINullable ) { // for perf I dont access property
                    if (_storage != null) 
                        defaultValue = _storage.NullValue; 
                    else if (this.isSqlType)
                        defaultValue = SqlConvert.ChangeType(defaultValue, this.dataType, FormatProvider); 
                    else if (this.implementsINullable) {
                        System.Reflection.PropertyInfo propInfo = this.dataType.GetProperty("Null", System.Reflection.BindingFlags.Public |System.Reflection.BindingFlags.Static);
                        if (propInfo  != null)
                            defaultValue = propInfo.GetValue(null, null); 
                    }
                } 
 
                return defaultValue;
            } 
            set {
                Bid.Trace(" %d#\n", ObjectID);
                if (defaultValue == null || ! DefaultValue.Equals(value)) {
                    if (AutoIncrement) { 
                        throw ExceptionBuilder.DefaultValueAndAutoIncrement();
                    } 
 
                    object newDefaultValue = (value == null) ? DBNull.Value : value;
                    if (newDefaultValue != DBNull.Value && DataType != typeof(Object)) { 
                        // If the DefualtValue is different from the Column DataType, we will coerce the value to the DataType
                        try {
                            newDefaultValue = SqlConvert.ChangeType(newDefaultValue, DataType, FormatProvider);
                        } 
                        catch (InvalidCastException) {
                            throw ExceptionBuilder.DefaultValueColumnDataType(ColumnName, DefaultValue.GetType(), DataType); 
                        } 
                    }
                    defaultValue = newDefaultValue; 
                    // SQL BU Defect Tracking 401640:  should not assign any value until conversion is successful.
                    defaultValueIsNull = ((newDefaultValue == DBNull.Value)||(this.ImplementsINullable && DataStorage.IsObjectSqlNull(newDefaultValue))) ? true:false;
                }
            } 
        }
 
        internal bool DefaultValueIsNull { 
            get {
                return defaultValueIsNull; 
            }
        }

        internal void BindExpression() { 
            this.DataExpression.Bind(this.table);
        } 
 
        /// 
        ///    Gets 
        ///       or sets the expresssion used to either filter rows, calculate the column's
        ///       value, or create an aggregate column.
        /// 
        [ 
        ResCategoryAttribute(Res.DataCategory_Data),
        RefreshProperties(RefreshProperties.All), 
        DefaultValue(""), 
        ResDescriptionAttribute(Res.DataColumnExpressionDescr)
        ] 
        public string Expression {
            get {
                return(this.expression == null ? "" : this.expression.Expression);
            } 
            set {
                IntPtr hscp; 
                Bid.ScopeEnter(out hscp, " %d#, '%ls'\n", ObjectID, value); 

                if (value == null) { 
                    value = "";
                }

                try { 
                    DataExpression newExpression = null;
                    if (value.Length > 0) { 
                        DataExpression testExpression = new DataExpression(this.table, value, this.dataType); 
                        if (testExpression.HasValue) {
                            newExpression = testExpression; 
                        }
                    }

                    if (expression == null && newExpression != null) { 
                        if (AutoIncrement || Unique) {
                            throw ExceptionBuilder.ExpressionAndUnique(); 
                        } 

                        // We need to make sure the column is not involved in any Constriants 
                        if (table != null) {
                            for (int i = 0; i < table.Constraints.Count; i++) {
                                if (table.Constraints[i].ContainsColumn(this)) {
                                    throw ExceptionBuilder.ExpressionAndConstraint(this, table.Constraints[i]); 
                                }
                            } 
                        } 

                        bool oldReadOnly = ReadOnly; 
                        try {
                            ReadOnly = true;
                        }
                        catch (ReadOnlyException e) { 
                            ExceptionBuilder.TraceExceptionForCapture(e);
                            ReadOnly = oldReadOnly; 
                            throw ExceptionBuilder.ExpressionAndReadOnly(); 
                        }
                    } 

                    // re-calculate the evaluation queue
                    if (this.table != null) {
                        if (newExpression != null && newExpression.DependsOn(this)) { 
                            throw ExceptionBuilder.ExpressionCircular();
                        } 
                        HandleDependentColumnList(expression, newExpression); 
                        //hold onto oldExpression in case of error applying new Expression.
                        DataExpression oldExpression = this.expression; 
                        this.expression = newExpression;

                        // because the column is attached to a table we need to re-calc values
                        try { 
                            if (newExpression == null) {
                                for (int i = 0; i < table.RecordCapacity; i++) { 
                                    InitializeRecord(i); 
                                }
                            } 
                            else {
                                this.table.EvaluateExpressions(this);
                            }
                            // SQLBU 501916: DataTable internal index is corrupted:'5' 
                            this.table.ResetInternalIndexes(this);
                            this.table.EvaluateDependentExpressions(this); 
                        } 
                        catch (Exception e1) {
                            // 
                            if (!ADP.IsCatchableExceptionType(e1)) {
                                throw;
                            }
                            ExceptionBuilder.TraceExceptionForCapture(e1); 
                            try {
                                // in the case of error we need to set the column expression to the old value 
                                this.expression = oldExpression; 
                                HandleDependentColumnList(newExpression, expression);
                                if (oldExpression == null) { 
                                    for (int i = 0; i < table.RecordCapacity; i++) {
                                        InitializeRecord(i);
                                    }
                                } 
                                else {
                                    this.table.EvaluateExpressions(this); 
                                } 
                                this.table.ResetInternalIndexes(this);
                                this.table.EvaluateDependentExpressions(this); 
                            }
                            catch(Exception e2) {
                                //
                                if (!ADP.IsCatchableExceptionType(e2)) { 
                                    throw;
                                } 
                                ExceptionBuilder.TraceExceptionWithoutRethrow(e2); 
                            }
                            throw; 
                        }
                    }
                    else {
                        //if column is not attached to a table, just set. 
                        this.expression = newExpression;
                    } 
                } 
                finally{
                    Bid.ScopeLeave(ref hscp); 
                }
            }
        }
 
        /// 
        ///    Gets the collection of custom user information. 
        ///  
        [
        ResCategoryAttribute(Res.DataCategory_Data), 
        Browsable(false),
        ResDescriptionAttribute(Res.ExtendedPropertiesDescr)
        ]
        public PropertyCollection ExtendedProperties { 
            get {
                if (extendedProperties == null) { 
                    extendedProperties = new PropertyCollection(); 
                }
                return extendedProperties; 
            }
        }

        ///  
        /// Indicates whether this column is now storing data.
        ///  
        internal bool HasData { 
            get {
                return (_storage != null); 
            }
        }

        internal bool ImplementsINullable { 
            get {
                return implementsINullable; 
            } 
        }
 
        internal bool ImplementsIChangeTracking {
            get {
                return implementsIChangeTracking;
            } 
        }
 
        internal bool ImplementsIRevertibleChangeTracking { 
            get {
                return implementsIRevertibleChangeTracking; 
            }
        }

        internal bool IsCloneable{ 
            get {
                Debug.Assert(null != _storage, "no storage"); 
                return _storage.IsCloneable; 
            }
        } 

        internal bool IsStringType {
            get {
                Debug.Assert(null != _storage, "no storage"); 
                return _storage.IsStringType;
            } 
        } 

        internal bool IsValueType { 
            get {
                Debug.Assert(null != _storage, "no storage");
                return _storage.IsValueType;
            } 
        }
 
        internal bool IsSqlType { 
            get {
                return isSqlType; 
            }
        }

        private void SetMaxLengthSimpleType() { 
            if (this.simpleType != null) {
                Debug.Assert (this.simpleType.CanHaveMaxLength(), "expected simpleType to be string"); 
 
                this.simpleType.MaxLength = maxLength;
                // check if we reset the simpleType back to plain string 
                if (this.simpleType.IsPlainString()) {
                    this.simpleType = null;
                }
                else { 
                    // Named Simple Type's Name should not be null
                    if (this.simpleType.Name != null && this.dttype != null) { 
                    // if MaxLength is changed, we need to make  namedsimpletype annonymous simpletype 
                        this.simpleType.ConvertToAnnonymousSimpleType();
                        this.dttype = null; 
                    }
                }
            }
            else if (-1 < maxLength) { 
                this.SimpleType = SimpleType.CreateLimitedStringType(maxLength);
            } 
        } 
        [
        ResCategoryAttribute(Res.DataCategory_Data), 
        ResDescriptionAttribute(Res.DataColumnMaxLengthDescr),
        DefaultValue(-1)
        ]
        public int MaxLength { 
            get {
                return maxLength; 
            } 
            set {
                IntPtr hscp; 
                Bid.ScopeEnter(out hscp, " %d#, %d\n", ObjectID, value);

                try {
                    if (maxLength != value) { 
                        if (this.ColumnMapping == MappingType.SimpleContent) {
                           throw ExceptionBuilder.CannotSetMaxLength2(this); 
                        } 
                        if ((DataType != typeof(string)) && (DataType != typeof(SqlString))) {
                           throw ExceptionBuilder.HasToBeStringType(this); 
                        }
                        int oldValue = maxLength;
                        maxLength = Math.Max(value, -1);
 
                        if (((oldValue < 0) || (value < oldValue)) && (null != table) && table.EnforceConstraints) {
                            if (!CheckMaxLength()) { 
                                maxLength = oldValue; 
                                throw ExceptionBuilder.CannotSetMaxLength(this, value);
                            } 
                        }
                        SetMaxLengthSimpleType();
                    }
                } 
                finally{
                    Bid.ScopeLeave(ref hscp); 
                } 
              }
        } 

        [
        ResCategoryAttribute(Res.DataCategory_Data),
        ResDescriptionAttribute(Res.DataColumnNamespaceDescr) 
        ]
        public string Namespace { 
            get { 
                if (_columnUri == null ) {
                    if (Table != null && columnMapping != MappingType.Attribute) { 
                        return Table.Namespace;
                    }
                    return "";
                } 
                return _columnUri;
            } 
            set { 
                Bid.Trace(" %d#, '%ls'\n", ObjectID, value);
 
                if (_columnUri != value) {
                    if (columnMapping != MappingType.SimpleContent) {
                        RaisePropertyChanging("Namespace");
                        _columnUri = value; 
                    }
                    else if (value != this.Namespace) { 
                        throw ExceptionBuilder.CannotChangeNamespace(this.ColumnName); 
                    }
                } 
            }
        }

        private bool ShouldSerializeNamespace() { 
            return (_columnUri != null);
        } 
 
        private void ResetNamespace() {
            this.Namespace = null; 
        }

        /// 
        ///     
        ///       Gets the position of the column in the 
        ///       collection. 
        ///     
        /// 
        [ 
        ResCategoryAttribute(Res.DataCategory_Data),
        Browsable(false),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
        ResDescriptionAttribute(Res.DataColumnOrdinalDescr) 
        ]
        public int Ordinal { 
            get { 
                return _ordinal;
            } 
        }

        public void SetOrdinal(int ordinal) {
            if (_ordinal == -1) { 
                throw ExceptionBuilder.ColumnNotInAnyTable();
            } 
 
            if (this._ordinal != ordinal) {
                table.Columns.MoveTo(this, ordinal); 
            }
        }

        internal void SetOrdinalInternal(int ordinal) { 
            //
            if (this._ordinal != ordinal) { 
                if (Unique && this._ordinal != -1 && ordinal == -1) { 
                    UniqueConstraint key =  table.Constraints.FindKeyConstraint(this);
                    if (key != null) 
                        table.Constraints.Remove(key);
                }
                // SQLBU 429176: remove the sortIndex when DataColumn is removed
                if ((null != sortIndex) && (-1 == ordinal)) { 
                    Debug.Assert(2 <= sortIndex.RefCount, "bad sortIndex refcount");
                    sortIndex.RemoveRef(); 
                    sortIndex.RemoveRef(); // second should remove it from index collection 
                    sortIndex = null;
                } 
                int originalOrdinal = this._ordinal;
                this._ordinal = ordinal;
                if (originalOrdinal == -1 && this._ordinal != -1) {
                    if (Unique) { 
                        UniqueConstraint key = new UniqueConstraint(this);
                        table.Constraints.Add(key); 
                    } 
                }
            } 
        }

        /// 
        ///     
        ///       Gets or sets a value
        ///       indicating whether the column allows changes once a row has been added to the table. 
        ///     
        /// 
        [ 
        ResCategoryAttribute(Res.DataCategory_Data),
        DefaultValue(false),
        ResDescriptionAttribute(Res.DataColumnReadOnlyDescr)
        ] 
        public bool ReadOnly {
            get { 
                return readOnly; 
            }
            set { 
                Bid.Trace(" %d#, %d{bool}\n", ObjectID, value);
                if (readOnly != value) {
                    if (!value && expression != null) {
                        throw ExceptionBuilder.ReadOnlyAndExpression(); 
                    }
                    this.readOnly = value; 
                } 
            }
        } 

        [DebuggerBrowsable(DebuggerBrowsableState.Never)] // don't have debugger view expand this
        private Index SortIndex {
            get { 
                if (sortIndex == null) {
                    IndexField[] indexDesc = new IndexField[] { new IndexField(this, false) }; 
                    sortIndex = table.GetIndex(indexDesc, DataViewRowState.CurrentRows, (IFilter) null); 
                    sortIndex.AddRef();
                } 
                return sortIndex;
            }
        }
 
        /// 
        ///     
        ///       Gets the  to which the column belongs to. 
        ///    
        ///  
        [
        ResCategoryAttribute(Res.DataCategory_Data),
        Browsable(false),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), 
        ResDescriptionAttribute(Res.DataColumnDataTableDescr)
        ] 
        public DataTable Table { 
            get {
                return table; 
            }
        }

        ///  
        /// Internal mechanism for changing the table pointer.
        ///  
        internal void SetTable(DataTable table) { 
            if (this.table != table) {
                if (this.Computed) 
                    if ((table == null) ||
                        (!table.fInitInProgress && ((table.DataSet == null) || (!table.DataSet.fIsSchemaLoading && !table.DataSet.fInitInProgress)))) {
                    // We need to re-bind all expression columns.
                    this.DataExpression.Bind(table); 
                }
 
                if (Unique && this.table != null) { 
                    UniqueConstraint constraint = table.Constraints.FindKeyConstraint(this);
                    if (constraint != null) 
                        table.Constraints.CanRemove(constraint, true);
                }
                this.table = table;
                _storage = null; // empty out storage for reuse. 
            }
        } 
 
        private DataRow GetDataRow(int index) {
            return table.recordManager[index]; 
        }

        /// 
        /// This is how data is pushed in and out of the column. 
        /// 
        internal object this[int record] { 
            get { 
                table.recordManager.VerifyRecord(record);
                Debug.Assert(null != _storage, "null storage"); 
                return _storage.Get(record);
            }
            set {
                try { 
                    table.recordManager.VerifyRecord(record);
                    Debug.Assert(null != _storage, "no storage"); 
                    Debug.Assert(null != value, "setting null, expecting dbnull"); 
                    _storage.Set(record, value);
                    Debug.Assert(null != this.table, "storage with no DataTable on column"); 
                }
                catch (Exception e) {
                    ExceptionBuilder.TraceExceptionForCapture(e);
                    throw ExceptionBuilder.SetFailed(value, this, DataType, e); 
                }
 
                if (autoIncrement){ 
                    if (!DataStorage.IsObjectNull(value)){
                        Int64 val64 = (Int64) SqlConvert.ChangeType2(value, StorageType.Int64, typeof(Int64), FormatProvider); 
                        if (autoIncrementStep > 0) {
                            if (val64 >= autoIncrementCurrent) {
                                autoIncrementCurrent = val64 + autoIncrementStep;
                            } 
                        }
                        else { 
                            if (val64 <= autoIncrementCurrent) { 
                                autoIncrementCurrent = val64 + autoIncrementStep;
                            } 
                        }
                    }
                }
 		if (Computed) {// if and only if it is Expression column, we will cache LastChangedColumn, otherwise DO NOT 
                    DataRow dr = GetDataRow(record);
                    if (dr != null) { 
                        // at initialization time (datatable.NewRow(), we would fill the storage with default value, but at that time we wont have datarow) 
                        dr.LastChangedColumn = this;
                    } 
                }
            }
        }
 
        internal void InitializeRecord(int record) {
            Debug.Assert(null != _storage, "no storage"); 
            _storage.Set(record, DefaultValue); 
        }
 
        internal void SetValue(int record, object value) { // just silently set the value
            try {
                Debug.Assert(null != value, "setting null, expecting dbnull");
                Debug.Assert(null != this.table, "storage with no DataTable on column"); 
                Debug.Assert(null != _storage, "no storage");
                _storage.Set(record, value); 
            } 
            catch (Exception e) {
                ExceptionBuilder.TraceExceptionForCapture(e); 
                throw ExceptionBuilder.SetFailed(value, this, DataType, e);
            }

            DataRow dr = GetDataRow(record); 
            if (dr != null) {  // at initialization time (datatable.NewRow(), we would fill the storage with default value, but at that time we wont have datarow)
                dr.LastChangedColumn = this; 
            } 
        }
 
        internal void FreeRecord(int record) {
            Debug.Assert(null != _storage, "no storage");
            _storage.Set(record, _storage.NullValue);
        } 

        ///  
        ///     
        ///       Gets or sets a value indicating whether the values in each row of the column must be unique.
        ///     
        /// 
        [
        ResCategoryAttribute(Res.DataCategory_Data),
        DefaultValue(false), 
        ResDescriptionAttribute(Res.DataColumnUniqueDescr),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden) 
        ] 
        public bool Unique {
            get { 
                return unique;
            }
            set {
                IntPtr hscp; 
                Bid.ScopeEnter(out hscp, " %d#, %d{bool}\n", ObjectID, value);
                try { 
                    if (unique != value) { 
                        if (value && expression != null) {
                            throw ExceptionBuilder.UniqueAndExpression(); 
                        }
                        UniqueConstraint oldConstraint = null;
                        if (table != null) {
                            if (value) 
                                CheckUnique();
                            else { 
                                for (System.Collections.IEnumerator e = Table.Constraints.GetEnumerator(); e.MoveNext();) { 
                                    UniqueConstraint o = (e.Current as UniqueConstraint);
                                    if ((null != o) && (o.ColumnsReference.Length == 1) && (o.ColumnsReference[0] == this)) 
                                        oldConstraint = o;
                                }
                                Debug.Assert(oldConstraint != null, "Should have found a column to remove from the collection.");
                                table.Constraints.CanRemove(oldConstraint, true); 
                            }
                        } 
 
                        this.unique = value;
 
                        if (table != null) {
                            if (value) {
                                // This should not fail due to a duplicate constraint. unique would have
                                // already been true if there was an existed UniqueConstraint for this column 

                                UniqueConstraint constraint = new UniqueConstraint(this); 
                                Debug.Assert(table.Constraints.FindKeyConstraint(this) == null, "Should not be a duplication constraint in collection"); 
                                table.Constraints.Add(constraint);
                            } 
                            else
                            {
                                table.Constraints.Remove(oldConstraint);
                                // 
                            }
                        } 
                    } 
                }
                finally { 
                    Bid.ScopeLeave(ref hscp);
                }
            }
         } 

 
// FxCop Rule; getter not used!  WebData 101301; so changing from Property to method 
        internal void InternalUnique(bool value) {
            this.unique = value; 
        }

        internal string XmlDataType {
            get { 
                return dttype;
            } 
            set { 
                dttype = value;
            } 
        }

        internal SimpleType SimpleType {
            get { 
                return simpleType;
            } 
            set { 
                simpleType = value;
// there is a change, since we are supporting hierarchy(bacause of Names Simple Type) old check (just one leel base check) is wrong 
                if (value!=null && value.CanHaveMaxLength())
                    maxLength = simpleType.MaxLength;// this is temp solution, since we dont let simple content to have
                    //maxlength set but for simple type we want to set it, after coming to decision about it , we should
                    // use MaxLength property 
            }
        } 
 
        /// 
        /// Gets the  of the column. 
        /// 
        [
        DefaultValue(MappingType.Element),
        ResDescriptionAttribute(Res.DataColumnMappingDescr) 
        ]
        public virtual MappingType ColumnMapping { 
            get { 
                return columnMapping;
            } 
            set {
                Bid.Trace(" %d#, %d{ds.MappingType}\n", ObjectID, (int)value);
                if(value != columnMapping) {
 
                    if (value == MappingType.SimpleContent && table != null) {
                        int threshold = 0; 
                        if (columnMapping == MappingType.Element) 
                            threshold = 1;
                        if (this.dataType == typeof(Char)) 
                            throw ExceptionBuilder.CannotSetSimpleContent(ColumnName, this.dataType);

                        if (table.XmlText != null && table.XmlText != this)
                            throw ExceptionBuilder.CannotAddColumn3(); 
                        if (table.ElementColumnCount > threshold)
                            throw ExceptionBuilder.CannotAddColumn4(this.ColumnName); 
                    } 

                    RaisePropertyChanging("ColumnMapping"); 

                    if (table!=null) {
                        if (columnMapping == MappingType.SimpleContent)
                            table.xmlText = null; 

                        if (value == MappingType.Element) 
                            table.ElementColumnCount ++; 
                        else if(columnMapping == MappingType.Element)
                            table.ElementColumnCount --; 
                    }

                    columnMapping = value;
                    if (value == MappingType.SimpleContent){ 
                        _columnUri = null;
                        if ( table != null) { 
                            table.XmlText = this; 
                        }
                        this.SimpleType = null; 
                    }
                }
            }
        } 

        internal void Description (string  value) { 
            if (value == null) 
                value = "";
            description = value; 
        }


        internal event PropertyChangedEventHandler PropertyChanging { 
            add {
                onPropertyChangingDelegate += value; 
            } 
            remove {
                onPropertyChangingDelegate -= value; 
            }
        }

        internal void CheckColumnConstraint(DataRow row, DataRowAction action) { 
            if (table.UpdatingCurrent(row, action)) {
                CheckNullable(row); 
                CheckMaxLength(row); 
            }
        } 

        internal bool CheckMaxLength() {
            if ((0 <= maxLength) && (null != Table) && (0 < Table.Rows.Count)) {
                Debug.Assert(IsStringType, "not a String or SqlString column"); 
                foreach(DataRow dr in Table.Rows) {
                    if (dr.HasVersion(DataRowVersion.Current)) { 
                        if (maxLength < GetStringLength(dr.GetCurrentRecordNo())) { 
                            return false;
                        } 
                    }
                }
            }
            return true; 
        }
 
        internal void CheckMaxLength(DataRow dr) { 
            if (0 <= maxLength) {
                Debug.Assert(IsStringType, "not a String or SqlString column"); 
                if (maxLength < GetStringLength(dr.GetDefaultRecord())) {
                    throw ExceptionBuilder.LongerThanMaxLength(this);
                }
            } 
        }
 
       internal protected void CheckNotAllowNull() { 
           if (_storage == null)
               return; 

           if (sortIndex != null) {
               if (sortIndex.IsKeyInIndex(_storage.NullValue)) {// here we do use strong typed NULL for Sql types
                   throw ExceptionBuilder.NullKeyValues(ColumnName); 
               }
            } 
            else { // since we do not have index, we so sequential search 
                foreach (DataRow dr in this.table.Rows) {
                    if (dr.RowState == DataRowState.Deleted) 
                        continue;
                    if (!implementsINullable){
                        if (dr[this] == DBNull.Value){
                            throw ExceptionBuilder.NullKeyValues(ColumnName); 
                        }
                    } 
                    else{ 
                        if (DataStorage.IsObjectNull(dr[this])){
                            throw ExceptionBuilder.NullKeyValues(ColumnName); 
                        }
                    }
                }
            } 
       }
 
        internal void CheckNullable(DataRow row) { 
            if (!AllowDBNull) {
                Debug.Assert(null != _storage, "no storage"); 
                if (_storage.IsNull(row.GetDefaultRecord())) {
                   throw ExceptionBuilder.NullValues(ColumnName);
               }
            } 
        }
 
        protected void CheckUnique() { 
            if (!SortIndex.CheckUnique()) {
                // Throws an exception and the name of any column if its Unique property set to 
                // True and non-unique values are found in the column.
                throw ExceptionBuilder.NonUniqueValues(ColumnName);
            }
        } 

        internal int Compare(int record1, int record2) { 
            Debug.Assert(null != _storage, "null storage"); 
            return _storage.Compare(record1, record2);
        } 

        internal bool CompareValueTo(int record1, object value, bool checkType) {
            // this method is used to make sure value and exact type match.
            int valuesMatch = CompareValueTo(record1, value); 
            // if values match according to storage, do extra checks for exact compare
            if (valuesMatch == 0) { 
                Type leftType = value.GetType(); 
                Type rightType = _storage.Get(record1).GetType();
                // if strings, then do exact character by character check 
                if (leftType == typeof(System.String) && rightType == typeof(System.String)) {
                    return String.CompareOrdinal((string)_storage.Get(record1), (string)value) == 0 ? true : false;
                }
                // make sure same type 
                else if (leftType== rightType) {
                    return true; 
                } 
            }
            return false; 
        }

        internal int CompareValueTo(int record1, object value) {
            Debug.Assert(null != _storage, "null storage"); 
            return _storage.CompareValueTo(record1, value);
        } 
 
        internal object ConvertValue(object value) {
            Debug.Assert(null != _storage, "null storage"); 
            return _storage.ConvertValue(value);
        }

        internal void Copy(int srcRecordNo, int dstRecordNo) { 
            Debug.Assert(null != _storage, "null storage");
            _storage.Copy(srcRecordNo, dstRecordNo); 
        } 

        internal DataColumn Clone() { 
            DataColumn clone = (DataColumn) Activator.CreateInstance(this.GetType());
            // set All properties
//            clone.columnMapping = columnMapping;
 
            clone.SimpleType = SimpleType;
 
            clone.allowNull = allowNull; 
            clone.autoIncrement = autoIncrement;
            clone.autoIncrementStep = autoIncrementStep; 
            clone.autoIncrementSeed = autoIncrementSeed;
            clone.autoIncrementCurrent = autoIncrementCurrent;
            clone.caption = caption;
            clone.ColumnName = ColumnName; 
            clone._columnUri = _columnUri;
            clone._columnPrefix = _columnPrefix; 
            clone.DataType = DataType; 
            clone.defaultValue = defaultValue;
            clone.defaultValueIsNull = ((defaultValue == DBNull.Value)||(clone.ImplementsINullable && DataStorage.IsObjectSqlNull(defaultValue))) ? true:false; 
            clone.columnMapping = columnMapping;// clone column Mapping since we dont let MaxLength to be set throu API
            //
            clone.readOnly = readOnly;
            clone.MaxLength = MaxLength; 
            clone.dttype = dttype;
            clone._dateTimeMode = _dateTimeMode; 
 

            // so if we have set it, we should continue preserving the information 

            // ...Extended Properties
            if (this.extendedProperties != null) {
                foreach(Object key in this.extendedProperties.Keys) { 
                    clone.ExtendedProperties[key]=this.extendedProperties[key];
                } 
            } 

            return clone; 
        }

        /// 
        ///    Finds a relation that this column is the sole child of or null. 
        /// 
        internal DataRelation FindParentRelation() { 
            DataRelation[] parentRelations = new DataRelation[Table.ParentRelations.Count]; 
            Table.ParentRelations.CopyTo(parentRelations, 0);
 
            for (int i = 0; i < parentRelations.Length; i++) {
                DataRelation relation = parentRelations[i];
                DataKey key = relation.ChildKey;
                if (key.ColumnsReference.Length == 1 && key.ColumnsReference[0] == this) { 
                    return relation;
                } 
            } 
            // should we throw an exception?
            return null; 
        }


        internal object GetAggregateValue(int[] records, AggregateType kind) { 
            if (_storage == null) {
                if (kind == AggregateType.Count) 
                    return 0; 
                else
                    return DBNull.Value; 
                }
            return _storage.Aggregate(records, kind);
        }
 
        private int GetStringLength(int record) {
            Debug.Assert(null != _storage, "no storage"); 
            return _storage.GetStringLength(record); 
        }
 
        internal void Init(int record) {
            if (AutoIncrement) {
                object value = autoIncrementCurrent;
                autoIncrementCurrent += autoIncrementStep; 
                Debug.Assert(null != _storage, "no storage");
                _storage.Set(record, value); 
            } 
            else
                this[record] = defaultValue; 
        }

        internal static bool IsAutoIncrementType(Type dataType) {
            return((dataType == typeof(Int32)) || (dataType == typeof(Int64)) || (dataType == typeof(Int16)) || (dataType == typeof(Decimal)) || 
                   (dataType == typeof(SqlInt32)) || (dataType == typeof(SqlInt64)) || (dataType == typeof(SqlInt16)) || (dataType == typeof(SqlDecimal)));
        } 
 
        private bool IsColumnMappingValid(StorageType typeCode, MappingType mapping){
            if ((mapping != MappingType.Element) && DataStorage.IsTypeCustomType(typeCode)) { 
                return false;
            }
            return true;
        } 

        internal bool IsCustomType { 
            get { 
                if (null != _storage)
                    return _storage.IsCustomDefinedType; 
                return DataStorage.IsTypeCustomType(DataType);
            }
        }
 
        internal bool IsValueCustomTypeInstance(object value) {
            // if instance is not a storage supported type (built in or SQL types) 
            return (DataStorage.IsTypeCustomType(value.GetType()) && !(value is Type)); 
        }
 
        internal bool ImplementsIXMLSerializable {
            get {
                return implementsIXMLSerializable;
            } 
        }
 
        internal bool IsNull(int record) { 
            Debug.Assert(null != _storage, "no storage");
            return _storage.IsNull(record); 
        }

        /// 
        ///      Returns true if this column is a part of a Parent or Child key for a relation. 
        /// 
        internal bool IsInRelation() { 
            DataKey key; 
            DataRelationCollection rels = table.ParentRelations;
 
            Debug.Assert(rels != null, "Invalid ParentRelations");
            for (int i = 0; i < rels.Count; i++) {
                key = rels[i].ChildKey;
                Debug.Assert(key.HasValue, "Invalid child key (null)"); 
                if (key.ContainsColumn(this)) {
                    return true; 
                } 
            }
            rels = table.ChildRelations; 
            Debug.Assert(rels != null, "Invalid ChildRelations");
            for (int i = 0; i < rels.Count; i++) {
                key = rels[i].ParentKey;
                Debug.Assert(key.HasValue, "Invalid parent key (null)"); 
                if (key.ContainsColumn(this)) {
                    return true; 
                } 
            }
            return false; 
        }

        internal bool IsMaxLengthViolated() {
            if (MaxLength < 0) 
                return true;
 
            bool error = false; 
            object value;
            string errorText = null; 

            foreach(DataRow dr in Table.Rows){
                if (dr.HasVersion(DataRowVersion.Current)) {
                    value = dr[this]; 
                    if (!this.isSqlType) {
                        if (value != null && value != DBNull.Value && ((string)value).Length > MaxLength) { 
                            if (errorText == null) { 
                                errorText = ExceptionBuilder.MaxLengthViolationText(this.ColumnName);
                            } 
                            dr.RowError = errorText;
                            dr.SetColumnError(this, errorText);
                            error = true;
                        } 
                    }
                    else{ 
                        if (!DataStorage.IsObjectNull(value)&& ((SqlString)value).Value.Length > MaxLength) { 
                            if (errorText == null) {
                                errorText = ExceptionBuilder.MaxLengthViolationText(this.ColumnName); 
                            }
                            dr.RowError = errorText;
                            dr.SetColumnError(this, errorText);
                            error = true; 
                        }
                    } 
                } 
            }
            return error; 
        }

        internal bool IsNotAllowDBNullViolated() {//
            Index index = this.SortIndex; 
            DataRow[] rows = index.GetRows(index.FindRecords(DBNull.Value));
            for (int i = 0; i < rows.Length; i++) { 
                string errorText = ExceptionBuilder.NotAllowDBNullViolationText(this.ColumnName); 
                rows[i].RowError = errorText;
                rows[i].SetColumnError(this, errorText); 
            }
            return (rows.Length > 0);
        }
 
        internal void FinishInitInProgress () {
            if (this.Computed) 
                BindExpression(); 
        }
 
        protected virtual void OnPropertyChanging(PropertyChangedEventArgs pcevent) {
            if (onPropertyChangingDelegate != null)
                onPropertyChangingDelegate(this, pcevent);
        } 

        protected internal void RaisePropertyChanging(string name) { 
            OnPropertyChanging(new PropertyChangedEventArgs(name)); 
        }
 
        private void InsureStorage() {
            if (_storage == null) {
                _storage = DataStorage.CreateStorage(this, dataType);
            } 
        }
 
        internal void  SetCapacity(int capacity) { 
            InsureStorage();
            _storage.SetCapacity(capacity); 
        }

        private bool ShouldSerializeDefaultValue() {
            return (!DefaultValueIsNull); 
        }
 
        internal void OnSetDataSet() { 
        }
 
        // Returns the  of the column, if one exists.
        public override string ToString() {
            if (this.expression == null)
                return this.ColumnName; 
            else
                return this.ColumnName + " + " + this.Expression; 
 
        }
 

        internal object ConvertXmlToObject(string s) {
            Debug.Assert(s != null, "Caller is resposible for missing element/attribure case");
            InsureStorage(); 
            return _storage.ConvertXmlToObject(s);
        } 
 
        internal object ConvertXmlToObject( XmlReader xmlReader, XmlRootAttribute xmlAttrib) {
            InsureStorage(); 
            return _storage.ConvertXmlToObject(xmlReader, xmlAttrib);
        }

 
        internal string ConvertObjectToXml(object value) {
            Debug.Assert(value != null && (value != DBNull.Value), "Caller is resposible for checking on DBNull"); 
            InsureStorage(); 
            return _storage.ConvertObjectToXml(value);
        } 

        internal void ConvertObjectToXml(object value, XmlWriter xmlWriter, XmlRootAttribute xmlAttrib) {
            Debug.Assert(value != null && (value != DBNull.Value), "Caller is resposible for checking on DBNull");
            InsureStorage(); 
            _storage.ConvertObjectToXml(value, xmlWriter, xmlAttrib);
        } 
 
        internal object GetEmptyColumnStore(int recordCount) {
            InsureStorage(); 
            return _storage.GetEmptyStorageInternal(recordCount);
        }

        internal void CopyValueIntoStore(int record, object store, BitArray nullbits, int storeIndex) { 
            Debug.Assert(null != _storage, "no storage");
            _storage.CopyValueInternal(record, store, nullbits, storeIndex); 
        } 

        internal void SetStorage(object store, BitArray nullbits) { 
            InsureStorage();
            _storage.SetStorageInternal(store, nullbits);
        }
 
        internal void AddDependentColumn(DataColumn expressionColumn) {
            if (dependentColumns == null) { 
                dependentColumns = new List(); 
            }
            Debug.Assert(!dependentColumns.Contains(expressionColumn), "duplicate column - expected to be unique"); 
            dependentColumns.Add(expressionColumn);
            this.table.AddDependentColumn(expressionColumn);
        }
 
        internal void RemoveDependentColumn(DataColumn expressionColumn) {
            if (dependentColumns != null && dependentColumns.Contains(expressionColumn)) { 
                dependentColumns.Remove(expressionColumn); 
            }
            this.table.RemoveDependentColumn(expressionColumn); 
        }

        internal void HandleDependentColumnList(DataExpression oldExpression, DataExpression newExpression) {
            DataColumn[] dependency; 
            // remove this column from the dependentColumn list of the columns this column depends on.
            if (oldExpression != null) { 
                dependency = oldExpression.GetDependency(); 
                foreach(DataColumn col in dependency) {
                    Debug.Assert(null != col, "null datacolumn in expression dependencies"); 
                    col.RemoveDependentColumn(this);
                    if (col.table != this.table) {
                        this.table.RemoveDependentColumn(this);
                    } 
                }
                this.table.RemoveDependentColumn(this); 
            } 

            if (newExpression != null) { 
                // get the list of columns that this expression depends on
                dependency = newExpression.GetDependency();
                // add this column to dependent column list of each column this column depends on
                foreach(DataColumn col in dependency) { 
                    col.AddDependentColumn(this);
                    if (col.table != this.table) { 
                        this.table.AddDependentColumn(this); 
                    }
                } 
                this.table.AddDependentColumn(this);
            }
        }
    } 
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// [....] 
// [....]
//----------------------------------------------------------------------------- 
 
namespace System.Data {
    using System; 
    using System.Xml;
    using System.Data.Common;
    using System.ComponentModel;
    using System.Diagnostics; 
    using System.Collections;
    using System.Globalization; 
    using System.Data.SqlTypes; 
    using System.Xml.Serialization;
    using System.Collections.Generic; 

    /// 
    ///    
    ///       Represents one column of data in a . 
    ///    
    ///  
    [ 
    ToolboxItem(false),
    DesignTimeVisible(false), 
    DefaultProperty("ColumnName"),
    Editor("Microsoft.VSDesigner.Data.Design.DataColumnEditor, " + AssemblyRef.MicrosoftVSDesigner, "System.Drawing.Design.UITypeEditor, " + AssemblyRef.SystemDrawing),
    ]
#if WINFSInternalOnly 
    internal
#else 
    public 
#endif
    class DataColumn : MarshalByValueComponent { 

        // properties
        private bool allowNull              = true;
        private bool autoIncrement          = false; 
        private Int64 autoIncrementStep       = 1;
        private Int64 autoIncrementSeed       = 0; 
        private string caption              = null; 
        private string _columnName          = null;
        private Type dataType               = null; 
        internal object defaultValue        = DBNull.Value;             // DefaultValue Converter
        private DataSetDateTime _dateTimeMode  =  DataSetDateTime.UnspecifiedLocal;
        private DataExpression expression   = null;
        private int maxLength             = -1; 
        private int _ordinal                = -1;
        private bool readOnly               = false; 
        internal Index sortIndex            = null; 
        internal DataTable table            = null;
        private bool unique                 = false; 
        internal MappingType columnMapping  = MappingType.Element;
        internal int _hashCode;

        internal int errors; 
        private bool isSqlType = false;
        private bool implementsINullable = false; 
        private bool implementsIChangeTracking = false; 
        private bool implementsIRevertibleChangeTracking = false;
        private bool implementsIXMLSerializable = false; 

        private bool defaultValueIsNull = true;

        // list of columns whose expression consume values from this column 
        internal List dependentColumns = null;
 
        // collections 
        internal PropertyCollection extendedProperties = null;
 
        // events
        private PropertyChangedEventHandler onPropertyChangingDelegate = null;

        // state 
        private DataStorage _storage;
        internal Int64 autoIncrementCurrent = 0; 
 
        //
        // The _columnClass member is the class for the unfoliated virtual nodes in the XML. 
        //
        internal string _columnUri        = null;
        private string _columnPrefix     = "";
        internal string encodedColumnName  = null; 

        // XML-specific Column Properties 
        internal string description = ""; 

        // 
        internal string dttype = "";        // The type specified in dt:type attribute
        internal SimpleType simpleType = null;

        private static int _objectTypeCount; // Bid counter 
        private readonly int _objectID = System.Threading.Interlocked.Increment(ref _objectTypeCount);
 
        ///  
        ///    
        ///       Initializes a new instance of a  
        ///       class.
        ///    
        /// 
        public DataColumn() : this(null, typeof(string), null, MappingType.Element) { 
        }
 
        ///  
        ///    
        ///       Inititalizes a new instance of the  class 
        ///       using the specified column name.
        ///    
        /// 
        public DataColumn(string columnName) : this(columnName, typeof(string), null, MappingType.Element) { 
        }
 
        ///  
        ///    
        ///       Inititalizes a new instance of the  class 
        ///       using the specified column name and data type.
        ///    
        /// 
        public DataColumn(string columnName, Type dataType) : this(columnName, dataType, null, MappingType.Element) { 
        }
 
        ///  
        ///    
        ///       Initializes a new instance 
        ///       of the  class
        ///       using the specified name, data type, and expression.
        ///    
        ///  
        public DataColumn(string columnName, Type dataType, string expr) : this(columnName, dataType, expr, MappingType.Element) {
        } 
 
        /// 
        ///     
        ///       Initializes a new instance of the  class
        ///       using
        ///       the specified name, data type, expression, and value that determines whether the
        ///       column is an attribute. 
        ///    
        ///  
        public DataColumn(string columnName, Type dataType, string expr, MappingType type) { 
            GC.SuppressFinalize(this);
            Bid.Trace(" %d#, columnName='%ls', expr='%ls', type=%d{ds.MappingType}\n", 
                          ObjectID, columnName, expr, (int)type);

            if (dataType == null) {
                throw ExceptionBuilder.ArgumentNull("dataType"); 
            }
 
            StorageType typeCode = DataStorage.GetStorageType(dataType); 
            if (DataStorage.ImplementsINullableValue(typeCode, dataType)) {
                throw ExceptionBuilder.ColumnTypeNotSupported(); 
            }
            _columnName = (columnName == null ? "" : columnName);

            SimpleType stype = SimpleType.CreateSimpleType(dataType); 
            if (null != stype) {
                this.SimpleType = stype; 
            } 
            UpdateColumnType(dataType, typeCode);
 
            if ((null != expr) && (0 < expr.Length)) {
                // @perfnote: its a performance hit to set Expression to the empty str when we know it will come out null
                this.Expression = expr;
            } 
            this.columnMapping = type;
        } 
 

        private void UpdateColumnType(Type type, StorageType typeCode) { 
            this.dataType = type;
            if (StorageType.DateTime != typeCode) { // revert _dateTimeMode back to default, when column type is changed
                _dateTimeMode =  DataSetDateTime.UnspecifiedLocal;
            } 
            DataStorage.ImplementsInterfaces(
                                typeCode, type, 
                                out isSqlType, 
                                out implementsINullable,
                                out implementsIXMLSerializable, 
                                out implementsIChangeTracking,
                                out implementsIRevertibleChangeTracking);

            if (!isSqlType && implementsINullable) { 
                SqlUdtStorage.GetStaticNullForUdtType(type);
            } 
        } 

        // PUBLIC PROPERTIES 

        /// 
        ///    
        ///       Gets or sets a value indicating whether null 
        ///       values are
        ///       allowed in this column for rows belonging to the table. 
        ///     
        /// 
        [ 
        ResCategoryAttribute(Res.DataCategory_Data),
        DefaultValue(true),
        ResDescriptionAttribute(Res.DataColumnAllowNullDescr)
        ] 
        public bool AllowDBNull {
            get { 
                return allowNull; 
            }
            set { 
                IntPtr hscp;
                Bid.ScopeEnter(out hscp, " %d#, %d{bool}\n", ObjectID, value);
                try {
                    if (allowNull != value) { 
                        if (table != null) {
                            if (!value && table.EnforceConstraints) 
                                CheckNotAllowNull(); 
                        }
                        this.allowNull = value; 
                    }
                    //
                }
                finally { 
                    Bid.ScopeLeave(ref hscp);
                } 
            } 
        }
 
        /// 
        ///    
        ///       Gets or
        ///       sets a value indicating whether the column automatically increments the value of the column for new 
        ///       rows added to the table.
        ///     
        ///  
        [
        ResCategoryAttribute(Res.DataCategory_Data), 
        RefreshProperties(RefreshProperties.All),
        DefaultValue(false),
        ResDescriptionAttribute(Res.DataColumnAutoIncrementDescr)
        ] 
        public bool AutoIncrement {
            get { 
                return autoIncrement; 
            }
            set { 
                Bid.Trace(" %d#, %d{bool}\n", ObjectID, value);
                if (autoIncrement != value) {
                    if (value) {
                        if (expression != null) { 
                            throw ExceptionBuilder.AutoIncrementAndExpression();
                        } 
//                        if (defaultValue != null && defaultValue != DBNull.Value) { 
                        if (!DefaultValueIsNull){
                            throw ExceptionBuilder.AutoIncrementAndDefaultValue(); 
                        }
                        if (!IsAutoIncrementType(DataType)) {
                            if (HasData) {
                                throw ExceptionBuilder.AutoIncrementCannotSetIfHasData(DataType.Name); 
                            }
                            DataType = typeof(int); 
                        } 
                    }
                    autoIncrement = value; 
                }
            }
        }
 
        /// 
        ///     
        ///       Gets 
        ///       or sets the starting value for a column that has its
        ///     property 
        ///       set to 
        ///       .
        ///    
        ///  
        [
        ResCategoryAttribute(Res.DataCategory_Data), 
        DefaultValue((Int64)0), 
        ResDescriptionAttribute(Res.DataColumnAutoIncrementSeedDescr)
        ] 
        public Int64 AutoIncrementSeed {
            get {
                return autoIncrementSeed;
            } 
            set {
                Bid.Trace(" %d#, %I64d\n", ObjectID, value); 
                if (autoIncrementSeed != value) { 
                    if (autoIncrementCurrent == autoIncrementSeed) {
                        autoIncrementCurrent = value; 
                    }

                    if (AutoIncrementStep > 0) {
                        if (autoIncrementCurrent < value) { 
                            autoIncrementCurrent = value;
                        } 
                    } 
                    else {
                        if (autoIncrementCurrent > value) { 
                            autoIncrementCurrent = value;
                        }
                    }
 
                    autoIncrementSeed = value;
                } 
            } 
        }
 
        /// 
        ///    
        ///       Gets or sets the increment used by a column with its 
        ///       property set to  
        ///       .
        ///     
        ///  
        [
        ResCategoryAttribute(Res.DataCategory_Data), 
        DefaultValue((Int64)1),
        ResDescriptionAttribute(Res.DataColumnAutoIncrementStepDescr)
        ]
        public Int64 AutoIncrementStep { 
            get {
                return autoIncrementStep; 
            } 
            set {
                Bid.Trace(" %d#, %I64d\n", ObjectID, value); 
                if (autoIncrementStep != value) {
                    if (value == 0)
                        throw ExceptionBuilder.AutoIncrementSeed();
                    if (autoIncrementCurrent != autoIncrementSeed) 
                        autoIncrementCurrent += (value - autoIncrementStep);
                    autoIncrementStep = value; 
                } 
            }
        } 

        /// 
        ///    
        ///       Gets or sets 
        ///       the caption for this column.
        ///     
        ///  
        [
        ResCategoryAttribute(Res.DataCategory_Data), 
        ResDescriptionAttribute(Res.DataColumnCaptionDescr)
        ]
        public string Caption {
            get { 
                return(caption != null) ? caption : _columnName;
            } 
            set { 
                if (value == null)
                    value = ""; 

                if (caption == null || String.Compare(caption, value, true, Locale) != 0) {
                    caption = value;
                } 
            }
        } 
 
        /// 
        ///     
        ///       Resets the  property to its previous value, or
        ///       to  .
        ///    
        ///  
        private void ResetCaption() {
            if (caption != null) { 
                caption = null; 
            }
        } 

        /// 
        ///    
        ///       Gets a value indicating whether the  has been explicitly set. 
        ///    
        ///  
        private bool ShouldSerializeCaption() { 
            return(caption != null);
        } 

        /// 
        ///    
        ///       Gets or sets the name of the column within the . 
        ///    
        ///  
        [ 
        RefreshProperties(RefreshProperties.All),
        ResCategoryAttribute(Res.DataCategory_Data), 
        DefaultValue(""),
        ResDescriptionAttribute(Res.DataColumnColumnNameDescr)
        ]
        public string ColumnName { 
            get {
                return _columnName; 
            } 
            set {
                IntPtr hscp; 
                Bid.ScopeEnter(out hscp, " %d#, '%ls'\n", ObjectID, value);
                try {
                    if (value == null) {
                        value = ""; 
                    }
 
                    if (String.Compare(_columnName, value, true, Locale) != 0) { 
                        if (table != null) {
                            if (value.Length == 0) 
                                throw ExceptionBuilder.ColumnNameRequired();

                            table.Columns.RegisterColumnName(value, this, (DataTable)null);
                            if (_columnName.Length != 0) 
                                table.Columns.UnregisterName(_columnName);
                        } 
 
                        RaisePropertyChanging("ColumnName");
                        _columnName = value; 
                        encodedColumnName = null;
                        if (table != null) {
                            table.Columns.OnColumnPropertyChanged(new CollectionChangeEventArgs(CollectionChangeAction.Refresh, this));
                        } 
                    }
                    else if (_columnName != value) { 
                        RaisePropertyChanging("ColumnName"); 
                        _columnName = value;
                        encodedColumnName = null; 
                        if (table != null) {
                            table.Columns.OnColumnPropertyChanged(new CollectionChangeEventArgs(CollectionChangeAction.Refresh, this));
                        }
                    } 
                }
                finally{ 
                    Bid.ScopeLeave(ref hscp); 
                }
            } 
        }

        internal string EncodedColumnName {
            get { 
                if ( this.encodedColumnName == null ) {
                    this.encodedColumnName = XmlConvert.EncodeLocalName( this.ColumnName ); 
                } 
                Debug.Assert( this.encodedColumnName != null && this.encodedColumnName.Length != 0);
                return this.encodedColumnName; 
            }
        }

        internal IFormatProvider FormatProvider { 
            get {
                // used for formating/parsing not comparing 
                return ((null != table) ? table.FormatProvider : CultureInfo.CurrentCulture); 
            }
        } 

        internal CultureInfo Locale {
            get {
                // used for comparing not formating/parsing 
                return ((null != table) ? table.Locale : CultureInfo.CurrentCulture);
            } 
        } 

        internal int ObjectID { 
            get {
                return _objectID;
            }
        } 

        [ 
        ResCategoryAttribute(Res.DataCategory_Data), 
        DefaultValue(""),
        ResDescriptionAttribute(Res.DataColumnPrefixDescr) 
        ]
        public string Prefix {
            get { return _columnPrefix;}
            set { 
                if (value == null)
                    value = ""; 
                Bid.Trace(" %d#, '%ls'\n", ObjectID, value); 

                if ((XmlConvert.DecodeName(value) == value) &&  (XmlConvert.EncodeName(value) != value)) 
                    throw ExceptionBuilder.InvalidPrefix(value);

                _columnPrefix = value;
 
            }
        } 
 
        // Return the field value as a string. If the field value is NULL, then NULL is return.
        // If the column type is string and it's value is empty, then the empty string is returned. 
        // If the column type is not string, or the column type is string and the value is not empty string, then a non-empty string is returned
        // This method does not throw any formatting exceptions, since we can always format the field value to a string.
        internal string GetColumnValueAsString( DataRow row, DataRowVersion version ) {
 
            object objValue = this[row.GetRecordFromVersion(version)];
 
            if (DataStorage.IsObjectNull(objValue)) { 
                return null;
            } 

            string value = ConvertObjectToXml(objValue);
            Debug.Assert(value != null);
 
            return value;
        } 
 
        /// 
        /// Whether this column computes values. 
        /// 
        internal bool Computed {
            get {
                return(this.expression == null ? false : true); 
            }
        } 
 
        /// 
        /// The internal expression object that computes the values. 
        /// 
        internal DataExpression DataExpression {
            get {
                return this.expression; 
            }
        } 
 
        /// 
        ///     
        ///       The type
        ///       of data stored in thecolumn.
        ///    
        ///  
        [
        ResCategoryAttribute(Res.DataCategory_Data), 
        DefaultValue(typeof(string)), 
        RefreshProperties(RefreshProperties.All),
        TypeConverter(typeof(ColumnTypeConverter)), 
        ResDescriptionAttribute(Res.DataColumnDataTypeDescr)
        ]
        public Type DataType {
            get { 
                return dataType;
            } 
            set { 
                if (dataType != value) {
                    if (HasData) { 
                        throw ExceptionBuilder.CantChangeDataType();
                    }
                    if (value == null) {
                        throw ExceptionBuilder.NullDataType(); 
                    }
                    StorageType typeCode = DataStorage.GetStorageType(value); 
                    if (DataStorage.ImplementsINullableValue(typeCode, value)) { 
                        throw ExceptionBuilder.ColumnTypeNotSupported();
                    } 
                    if (table != null && IsInRelation()) {
                        throw ExceptionBuilder.ColumnsTypeMismatch();
                    }
 
                    // If the DefualtValue is different from the Column DataType, we will coerce the value to the DataType
                    if (!DefaultValueIsNull){ 
                        try { 
                          if (typeof(string) == value) {// since string types can be null in value! DO NOT REMOVE THIS
                                defaultValue = DefaultValue.ToString(); 
                          }
                          else if (typeof(SqlString) == value){// since string types can be null in value! DO NOT REMOVE THIS
                              defaultValue = SqlConvert.ConvertToSqlString(DefaultValue);
                          } 
                          else if (typeof(object) != value) {
                                DefaultValue = SqlConvert.ChangeType(DefaultValue, value, FormatProvider); 
                          } 
                        }
                        catch (InvalidCastException) { 
                            throw ExceptionBuilder.DefaultValueDataType(ColumnName, DefaultValue.GetType(), value);
                        }
                        catch (FormatException) {
                            throw ExceptionBuilder.DefaultValueDataType(ColumnName, DefaultValue.GetType(), value); 
                        }
                    } 
 
                    if (this.ColumnMapping == MappingType.SimpleContent)
                        if (value == typeof(Char)) 
                            throw ExceptionBuilder.CannotSetSimpleContentType(ColumnName, value);

                    SimpleType = SimpleType.CreateSimpleType(value);
                    if (StorageType.String == typeCode) { 
                        maxLength = -1;
                    } 
                    UpdateColumnType(value, typeCode); 
                    XmlDataType = null;
 
                    if (AutoIncrement && !IsAutoIncrementType(value)) {
                        AutoIncrement = false;
                    }
                } 
            }
        } 
 
        [
        ResCategoryAttribute(Res.DataCategory_Data), 
        DefaultValue(DataSetDateTime.UnspecifiedLocal),
        RefreshProperties(RefreshProperties.All),
        ResDescriptionAttribute(Res.DataColumnDateTimeModeDescr)
        ] 
        public DataSetDateTime DateTimeMode {
            get { 
                return _dateTimeMode; 
            }
            set { 
                if (_dateTimeMode != value) {
                    if (DataType != typeof(DateTime) && value != DataSetDateTime.UnspecifiedLocal) { //Check for column being DateTime. If the column is not DateTime make sure the value that is being is only the default[UnspecifiedLocal].
                        throw ExceptionBuilder.CannotSetDateTimeModeForNonDateTimeColumns();
                    } 
                    switch(value) {
                        case DataSetDateTime.Utc: 
                        case DataSetDateTime.Local: 
                            if (HasData) {
                                throw ExceptionBuilder.CantChangeDateTimeMode(_dateTimeMode, value); 
                            }
                            break;
                        case DataSetDateTime.Unspecified:
                        case DataSetDateTime.UnspecifiedLocal: 
                            if (_dateTimeMode == DataSetDateTime.Unspecified || _dateTimeMode == DataSetDateTime.UnspecifiedLocal) {
                                break; 
                            } 
                            if (HasData) {
                                throw ExceptionBuilder.CantChangeDateTimeMode(_dateTimeMode, value); 
                            }
                            break;
                        default :
                            throw ExceptionBuilder.InvalidDateTimeMode(value); 
                    }
                    _dateTimeMode = value; 
                } 
            }
        } 

        /// 
        ///    Gets or sets the default value for the
        ///       column when creating new rows. 
        /// 
        [ 
        ResCategoryAttribute(Res.DataCategory_Data), 
        ResDescriptionAttribute(Res.DataColumnDefaultValueDescr),
        TypeConverter(typeof(DefaultValueTypeConverter)) 
        ]
        public object DefaultValue {
            get {
                Debug.Assert(defaultValue != null, "It should not have been set to null."); 
                if (defaultValue == DBNull.Value && this.implementsINullable ) { // for perf I dont access property
                    if (_storage != null) 
                        defaultValue = _storage.NullValue; 
                    else if (this.isSqlType)
                        defaultValue = SqlConvert.ChangeType(defaultValue, this.dataType, FormatProvider); 
                    else if (this.implementsINullable) {
                        System.Reflection.PropertyInfo propInfo = this.dataType.GetProperty("Null", System.Reflection.BindingFlags.Public |System.Reflection.BindingFlags.Static);
                        if (propInfo  != null)
                            defaultValue = propInfo.GetValue(null, null); 
                    }
                } 
 
                return defaultValue;
            } 
            set {
                Bid.Trace(" %d#\n", ObjectID);
                if (defaultValue == null || ! DefaultValue.Equals(value)) {
                    if (AutoIncrement) { 
                        throw ExceptionBuilder.DefaultValueAndAutoIncrement();
                    } 
 
                    object newDefaultValue = (value == null) ? DBNull.Value : value;
                    if (newDefaultValue != DBNull.Value && DataType != typeof(Object)) { 
                        // If the DefualtValue is different from the Column DataType, we will coerce the value to the DataType
                        try {
                            newDefaultValue = SqlConvert.ChangeType(newDefaultValue, DataType, FormatProvider);
                        } 
                        catch (InvalidCastException) {
                            throw ExceptionBuilder.DefaultValueColumnDataType(ColumnName, DefaultValue.GetType(), DataType); 
                        } 
                    }
                    defaultValue = newDefaultValue; 
                    // SQL BU Defect Tracking 401640:  should not assign any value until conversion is successful.
                    defaultValueIsNull = ((newDefaultValue == DBNull.Value)||(this.ImplementsINullable && DataStorage.IsObjectSqlNull(newDefaultValue))) ? true:false;
                }
            } 
        }
 
        internal bool DefaultValueIsNull { 
            get {
                return defaultValueIsNull; 
            }
        }

        internal void BindExpression() { 
            this.DataExpression.Bind(this.table);
        } 
 
        /// 
        ///    Gets 
        ///       or sets the expresssion used to either filter rows, calculate the column's
        ///       value, or create an aggregate column.
        /// 
        [ 
        ResCategoryAttribute(Res.DataCategory_Data),
        RefreshProperties(RefreshProperties.All), 
        DefaultValue(""), 
        ResDescriptionAttribute(Res.DataColumnExpressionDescr)
        ] 
        public string Expression {
            get {
                return(this.expression == null ? "" : this.expression.Expression);
            } 
            set {
                IntPtr hscp; 
                Bid.ScopeEnter(out hscp, " %d#, '%ls'\n", ObjectID, value); 

                if (value == null) { 
                    value = "";
                }

                try { 
                    DataExpression newExpression = null;
                    if (value.Length > 0) { 
                        DataExpression testExpression = new DataExpression(this.table, value, this.dataType); 
                        if (testExpression.HasValue) {
                            newExpression = testExpression; 
                        }
                    }

                    if (expression == null && newExpression != null) { 
                        if (AutoIncrement || Unique) {
                            throw ExceptionBuilder.ExpressionAndUnique(); 
                        } 

                        // We need to make sure the column is not involved in any Constriants 
                        if (table != null) {
                            for (int i = 0; i < table.Constraints.Count; i++) {
                                if (table.Constraints[i].ContainsColumn(this)) {
                                    throw ExceptionBuilder.ExpressionAndConstraint(this, table.Constraints[i]); 
                                }
                            } 
                        } 

                        bool oldReadOnly = ReadOnly; 
                        try {
                            ReadOnly = true;
                        }
                        catch (ReadOnlyException e) { 
                            ExceptionBuilder.TraceExceptionForCapture(e);
                            ReadOnly = oldReadOnly; 
                            throw ExceptionBuilder.ExpressionAndReadOnly(); 
                        }
                    } 

                    // re-calculate the evaluation queue
                    if (this.table != null) {
                        if (newExpression != null && newExpression.DependsOn(this)) { 
                            throw ExceptionBuilder.ExpressionCircular();
                        } 
                        HandleDependentColumnList(expression, newExpression); 
                        //hold onto oldExpression in case of error applying new Expression.
                        DataExpression oldExpression = this.expression; 
                        this.expression = newExpression;

                        // because the column is attached to a table we need to re-calc values
                        try { 
                            if (newExpression == null) {
                                for (int i = 0; i < table.RecordCapacity; i++) { 
                                    InitializeRecord(i); 
                                }
                            } 
                            else {
                                this.table.EvaluateExpressions(this);
                            }
                            // SQLBU 501916: DataTable internal index is corrupted:'5' 
                            this.table.ResetInternalIndexes(this);
                            this.table.EvaluateDependentExpressions(this); 
                        } 
                        catch (Exception e1) {
                            // 
                            if (!ADP.IsCatchableExceptionType(e1)) {
                                throw;
                            }
                            ExceptionBuilder.TraceExceptionForCapture(e1); 
                            try {
                                // in the case of error we need to set the column expression to the old value 
                                this.expression = oldExpression; 
                                HandleDependentColumnList(newExpression, expression);
                                if (oldExpression == null) { 
                                    for (int i = 0; i < table.RecordCapacity; i++) {
                                        InitializeRecord(i);
                                    }
                                } 
                                else {
                                    this.table.EvaluateExpressions(this); 
                                } 
                                this.table.ResetInternalIndexes(this);
                                this.table.EvaluateDependentExpressions(this); 
                            }
                            catch(Exception e2) {
                                //
                                if (!ADP.IsCatchableExceptionType(e2)) { 
                                    throw;
                                } 
                                ExceptionBuilder.TraceExceptionWithoutRethrow(e2); 
                            }
                            throw; 
                        }
                    }
                    else {
                        //if column is not attached to a table, just set. 
                        this.expression = newExpression;
                    } 
                } 
                finally{
                    Bid.ScopeLeave(ref hscp); 
                }
            }
        }
 
        /// 
        ///    Gets the collection of custom user information. 
        ///  
        [
        ResCategoryAttribute(Res.DataCategory_Data), 
        Browsable(false),
        ResDescriptionAttribute(Res.ExtendedPropertiesDescr)
        ]
        public PropertyCollection ExtendedProperties { 
            get {
                if (extendedProperties == null) { 
                    extendedProperties = new PropertyCollection(); 
                }
                return extendedProperties; 
            }
        }

        ///  
        /// Indicates whether this column is now storing data.
        ///  
        internal bool HasData { 
            get {
                return (_storage != null); 
            }
        }

        internal bool ImplementsINullable { 
            get {
                return implementsINullable; 
            } 
        }
 
        internal bool ImplementsIChangeTracking {
            get {
                return implementsIChangeTracking;
            } 
        }
 
        internal bool ImplementsIRevertibleChangeTracking { 
            get {
                return implementsIRevertibleChangeTracking; 
            }
        }

        internal bool IsCloneable{ 
            get {
                Debug.Assert(null != _storage, "no storage"); 
                return _storage.IsCloneable; 
            }
        } 

        internal bool IsStringType {
            get {
                Debug.Assert(null != _storage, "no storage"); 
                return _storage.IsStringType;
            } 
        } 

        internal bool IsValueType { 
            get {
                Debug.Assert(null != _storage, "no storage");
                return _storage.IsValueType;
            } 
        }
 
        internal bool IsSqlType { 
            get {
                return isSqlType; 
            }
        }

        private void SetMaxLengthSimpleType() { 
            if (this.simpleType != null) {
                Debug.Assert (this.simpleType.CanHaveMaxLength(), "expected simpleType to be string"); 
 
                this.simpleType.MaxLength = maxLength;
                // check if we reset the simpleType back to plain string 
                if (this.simpleType.IsPlainString()) {
                    this.simpleType = null;
                }
                else { 
                    // Named Simple Type's Name should not be null
                    if (this.simpleType.Name != null && this.dttype != null) { 
                    // if MaxLength is changed, we need to make  namedsimpletype annonymous simpletype 
                        this.simpleType.ConvertToAnnonymousSimpleType();
                        this.dttype = null; 
                    }
                }
            }
            else if (-1 < maxLength) { 
                this.SimpleType = SimpleType.CreateLimitedStringType(maxLength);
            } 
        } 
        [
        ResCategoryAttribute(Res.DataCategory_Data), 
        ResDescriptionAttribute(Res.DataColumnMaxLengthDescr),
        DefaultValue(-1)
        ]
        public int MaxLength { 
            get {
                return maxLength; 
            } 
            set {
                IntPtr hscp; 
                Bid.ScopeEnter(out hscp, " %d#, %d\n", ObjectID, value);

                try {
                    if (maxLength != value) { 
                        if (this.ColumnMapping == MappingType.SimpleContent) {
                           throw ExceptionBuilder.CannotSetMaxLength2(this); 
                        } 
                        if ((DataType != typeof(string)) && (DataType != typeof(SqlString))) {
                           throw ExceptionBuilder.HasToBeStringType(this); 
                        }
                        int oldValue = maxLength;
                        maxLength = Math.Max(value, -1);
 
                        if (((oldValue < 0) || (value < oldValue)) && (null != table) && table.EnforceConstraints) {
                            if (!CheckMaxLength()) { 
                                maxLength = oldValue; 
                                throw ExceptionBuilder.CannotSetMaxLength(this, value);
                            } 
                        }
                        SetMaxLengthSimpleType();
                    }
                } 
                finally{
                    Bid.ScopeLeave(ref hscp); 
                } 
              }
        } 

        [
        ResCategoryAttribute(Res.DataCategory_Data),
        ResDescriptionAttribute(Res.DataColumnNamespaceDescr) 
        ]
        public string Namespace { 
            get { 
                if (_columnUri == null ) {
                    if (Table != null && columnMapping != MappingType.Attribute) { 
                        return Table.Namespace;
                    }
                    return "";
                } 
                return _columnUri;
            } 
            set { 
                Bid.Trace(" %d#, '%ls'\n", ObjectID, value);
 
                if (_columnUri != value) {
                    if (columnMapping != MappingType.SimpleContent) {
                        RaisePropertyChanging("Namespace");
                        _columnUri = value; 
                    }
                    else if (value != this.Namespace) { 
                        throw ExceptionBuilder.CannotChangeNamespace(this.ColumnName); 
                    }
                } 
            }
        }

        private bool ShouldSerializeNamespace() { 
            return (_columnUri != null);
        } 
 
        private void ResetNamespace() {
            this.Namespace = null; 
        }

        /// 
        ///     
        ///       Gets the position of the column in the 
        ///       collection. 
        ///     
        /// 
        [ 
        ResCategoryAttribute(Res.DataCategory_Data),
        Browsable(false),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
        ResDescriptionAttribute(Res.DataColumnOrdinalDescr) 
        ]
        public int Ordinal { 
            get { 
                return _ordinal;
            } 
        }

        public void SetOrdinal(int ordinal) {
            if (_ordinal == -1) { 
                throw ExceptionBuilder.ColumnNotInAnyTable();
            } 
 
            if (this._ordinal != ordinal) {
                table.Columns.MoveTo(this, ordinal); 
            }
        }

        internal void SetOrdinalInternal(int ordinal) { 
            //
            if (this._ordinal != ordinal) { 
                if (Unique && this._ordinal != -1 && ordinal == -1) { 
                    UniqueConstraint key =  table.Constraints.FindKeyConstraint(this);
                    if (key != null) 
                        table.Constraints.Remove(key);
                }
                // SQLBU 429176: remove the sortIndex when DataColumn is removed
                if ((null != sortIndex) && (-1 == ordinal)) { 
                    Debug.Assert(2 <= sortIndex.RefCount, "bad sortIndex refcount");
                    sortIndex.RemoveRef(); 
                    sortIndex.RemoveRef(); // second should remove it from index collection 
                    sortIndex = null;
                } 
                int originalOrdinal = this._ordinal;
                this._ordinal = ordinal;
                if (originalOrdinal == -1 && this._ordinal != -1) {
                    if (Unique) { 
                        UniqueConstraint key = new UniqueConstraint(this);
                        table.Constraints.Add(key); 
                    } 
                }
            } 
        }

        /// 
        ///     
        ///       Gets or sets a value
        ///       indicating whether the column allows changes once a row has been added to the table. 
        ///     
        /// 
        [ 
        ResCategoryAttribute(Res.DataCategory_Data),
        DefaultValue(false),
        ResDescriptionAttribute(Res.DataColumnReadOnlyDescr)
        ] 
        public bool ReadOnly {
            get { 
                return readOnly; 
            }
            set { 
                Bid.Trace(" %d#, %d{bool}\n", ObjectID, value);
                if (readOnly != value) {
                    if (!value && expression != null) {
                        throw ExceptionBuilder.ReadOnlyAndExpression(); 
                    }
                    this.readOnly = value; 
                } 
            }
        } 

        [DebuggerBrowsable(DebuggerBrowsableState.Never)] // don't have debugger view expand this
        private Index SortIndex {
            get { 
                if (sortIndex == null) {
                    IndexField[] indexDesc = new IndexField[] { new IndexField(this, false) }; 
                    sortIndex = table.GetIndex(indexDesc, DataViewRowState.CurrentRows, (IFilter) null); 
                    sortIndex.AddRef();
                } 
                return sortIndex;
            }
        }
 
        /// 
        ///     
        ///       Gets the  to which the column belongs to. 
        ///    
        ///  
        [
        ResCategoryAttribute(Res.DataCategory_Data),
        Browsable(false),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), 
        ResDescriptionAttribute(Res.DataColumnDataTableDescr)
        ] 
        public DataTable Table { 
            get {
                return table; 
            }
        }

        ///  
        /// Internal mechanism for changing the table pointer.
        ///  
        internal void SetTable(DataTable table) { 
            if (this.table != table) {
                if (this.Computed) 
                    if ((table == null) ||
                        (!table.fInitInProgress && ((table.DataSet == null) || (!table.DataSet.fIsSchemaLoading && !table.DataSet.fInitInProgress)))) {
                    // We need to re-bind all expression columns.
                    this.DataExpression.Bind(table); 
                }
 
                if (Unique && this.table != null) { 
                    UniqueConstraint constraint = table.Constraints.FindKeyConstraint(this);
                    if (constraint != null) 
                        table.Constraints.CanRemove(constraint, true);
                }
                this.table = table;
                _storage = null; // empty out storage for reuse. 
            }
        } 
 
        private DataRow GetDataRow(int index) {
            return table.recordManager[index]; 
        }

        /// 
        /// This is how data is pushed in and out of the column. 
        /// 
        internal object this[int record] { 
            get { 
                table.recordManager.VerifyRecord(record);
                Debug.Assert(null != _storage, "null storage"); 
                return _storage.Get(record);
            }
            set {
                try { 
                    table.recordManager.VerifyRecord(record);
                    Debug.Assert(null != _storage, "no storage"); 
                    Debug.Assert(null != value, "setting null, expecting dbnull"); 
                    _storage.Set(record, value);
                    Debug.Assert(null != this.table, "storage with no DataTable on column"); 
                }
                catch (Exception e) {
                    ExceptionBuilder.TraceExceptionForCapture(e);
                    throw ExceptionBuilder.SetFailed(value, this, DataType, e); 
                }
 
                if (autoIncrement){ 
                    if (!DataStorage.IsObjectNull(value)){
                        Int64 val64 = (Int64) SqlConvert.ChangeType2(value, StorageType.Int64, typeof(Int64), FormatProvider); 
                        if (autoIncrementStep > 0) {
                            if (val64 >= autoIncrementCurrent) {
                                autoIncrementCurrent = val64 + autoIncrementStep;
                            } 
                        }
                        else { 
                            if (val64 <= autoIncrementCurrent) { 
                                autoIncrementCurrent = val64 + autoIncrementStep;
                            } 
                        }
                    }
                }
 		if (Computed) {// if and only if it is Expression column, we will cache LastChangedColumn, otherwise DO NOT 
                    DataRow dr = GetDataRow(record);
                    if (dr != null) { 
                        // at initialization time (datatable.NewRow(), we would fill the storage with default value, but at that time we wont have datarow) 
                        dr.LastChangedColumn = this;
                    } 
                }
            }
        }
 
        internal void InitializeRecord(int record) {
            Debug.Assert(null != _storage, "no storage"); 
            _storage.Set(record, DefaultValue); 
        }
 
        internal void SetValue(int record, object value) { // just silently set the value
            try {
                Debug.Assert(null != value, "setting null, expecting dbnull");
                Debug.Assert(null != this.table, "storage with no DataTable on column"); 
                Debug.Assert(null != _storage, "no storage");
                _storage.Set(record, value); 
            } 
            catch (Exception e) {
                ExceptionBuilder.TraceExceptionForCapture(e); 
                throw ExceptionBuilder.SetFailed(value, this, DataType, e);
            }

            DataRow dr = GetDataRow(record); 
            if (dr != null) {  // at initialization time (datatable.NewRow(), we would fill the storage with default value, but at that time we wont have datarow)
                dr.LastChangedColumn = this; 
            } 
        }
 
        internal void FreeRecord(int record) {
            Debug.Assert(null != _storage, "no storage");
            _storage.Set(record, _storage.NullValue);
        } 

        ///  
        ///     
        ///       Gets or sets a value indicating whether the values in each row of the column must be unique.
        ///     
        /// 
        [
        ResCategoryAttribute(Res.DataCategory_Data),
        DefaultValue(false), 
        ResDescriptionAttribute(Res.DataColumnUniqueDescr),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden) 
        ] 
        public bool Unique {
            get { 
                return unique;
            }
            set {
                IntPtr hscp; 
                Bid.ScopeEnter(out hscp, " %d#, %d{bool}\n", ObjectID, value);
                try { 
                    if (unique != value) { 
                        if (value && expression != null) {
                            throw ExceptionBuilder.UniqueAndExpression(); 
                        }
                        UniqueConstraint oldConstraint = null;
                        if (table != null) {
                            if (value) 
                                CheckUnique();
                            else { 
                                for (System.Collections.IEnumerator e = Table.Constraints.GetEnumerator(); e.MoveNext();) { 
                                    UniqueConstraint o = (e.Current as UniqueConstraint);
                                    if ((null != o) && (o.ColumnsReference.Length == 1) && (o.ColumnsReference[0] == this)) 
                                        oldConstraint = o;
                                }
                                Debug.Assert(oldConstraint != null, "Should have found a column to remove from the collection.");
                                table.Constraints.CanRemove(oldConstraint, true); 
                            }
                        } 
 
                        this.unique = value;
 
                        if (table != null) {
                            if (value) {
                                // This should not fail due to a duplicate constraint. unique would have
                                // already been true if there was an existed UniqueConstraint for this column 

                                UniqueConstraint constraint = new UniqueConstraint(this); 
                                Debug.Assert(table.Constraints.FindKeyConstraint(this) == null, "Should not be a duplication constraint in collection"); 
                                table.Constraints.Add(constraint);
                            } 
                            else
                            {
                                table.Constraints.Remove(oldConstraint);
                                // 
                            }
                        } 
                    } 
                }
                finally { 
                    Bid.ScopeLeave(ref hscp);
                }
            }
         } 

 
// FxCop Rule; getter not used!  WebData 101301; so changing from Property to method 
        internal void InternalUnique(bool value) {
            this.unique = value; 
        }

        internal string XmlDataType {
            get { 
                return dttype;
            } 
            set { 
                dttype = value;
            } 
        }

        internal SimpleType SimpleType {
            get { 
                return simpleType;
            } 
            set { 
                simpleType = value;
// there is a change, since we are supporting hierarchy(bacause of Names Simple Type) old check (just one leel base check) is wrong 
                if (value!=null && value.CanHaveMaxLength())
                    maxLength = simpleType.MaxLength;// this is temp solution, since we dont let simple content to have
                    //maxlength set but for simple type we want to set it, after coming to decision about it , we should
                    // use MaxLength property 
            }
        } 
 
        /// 
        /// Gets the  of the column. 
        /// 
        [
        DefaultValue(MappingType.Element),
        ResDescriptionAttribute(Res.DataColumnMappingDescr) 
        ]
        public virtual MappingType ColumnMapping { 
            get { 
                return columnMapping;
            } 
            set {
                Bid.Trace(" %d#, %d{ds.MappingType}\n", ObjectID, (int)value);
                if(value != columnMapping) {
 
                    if (value == MappingType.SimpleContent && table != null) {
                        int threshold = 0; 
                        if (columnMapping == MappingType.Element) 
                            threshold = 1;
                        if (this.dataType == typeof(Char)) 
                            throw ExceptionBuilder.CannotSetSimpleContent(ColumnName, this.dataType);

                        if (table.XmlText != null && table.XmlText != this)
                            throw ExceptionBuilder.CannotAddColumn3(); 
                        if (table.ElementColumnCount > threshold)
                            throw ExceptionBuilder.CannotAddColumn4(this.ColumnName); 
                    } 

                    RaisePropertyChanging("ColumnMapping"); 

                    if (table!=null) {
                        if (columnMapping == MappingType.SimpleContent)
                            table.xmlText = null; 

                        if (value == MappingType.Element) 
                            table.ElementColumnCount ++; 
                        else if(columnMapping == MappingType.Element)
                            table.ElementColumnCount --; 
                    }

                    columnMapping = value;
                    if (value == MappingType.SimpleContent){ 
                        _columnUri = null;
                        if ( table != null) { 
                            table.XmlText = this; 
                        }
                        this.SimpleType = null; 
                    }
                }
            }
        } 

        internal void Description (string  value) { 
            if (value == null) 
                value = "";
            description = value; 
        }


        internal event PropertyChangedEventHandler PropertyChanging { 
            add {
                onPropertyChangingDelegate += value; 
            } 
            remove {
                onPropertyChangingDelegate -= value; 
            }
        }

        internal void CheckColumnConstraint(DataRow row, DataRowAction action) { 
            if (table.UpdatingCurrent(row, action)) {
                CheckNullable(row); 
                CheckMaxLength(row); 
            }
        } 

        internal bool CheckMaxLength() {
            if ((0 <= maxLength) && (null != Table) && (0 < Table.Rows.Count)) {
                Debug.Assert(IsStringType, "not a String or SqlString column"); 
                foreach(DataRow dr in Table.Rows) {
                    if (dr.HasVersion(DataRowVersion.Current)) { 
                        if (maxLength < GetStringLength(dr.GetCurrentRecordNo())) { 
                            return false;
                        } 
                    }
                }
            }
            return true; 
        }
 
        internal void CheckMaxLength(DataRow dr) { 
            if (0 <= maxLength) {
                Debug.Assert(IsStringType, "not a String or SqlString column"); 
                if (maxLength < GetStringLength(dr.GetDefaultRecord())) {
                    throw ExceptionBuilder.LongerThanMaxLength(this);
                }
            } 
        }
 
       internal protected void CheckNotAllowNull() { 
           if (_storage == null)
               return; 

           if (sortIndex != null) {
               if (sortIndex.IsKeyInIndex(_storage.NullValue)) {// here we do use strong typed NULL for Sql types
                   throw ExceptionBuilder.NullKeyValues(ColumnName); 
               }
            } 
            else { // since we do not have index, we so sequential search 
                foreach (DataRow dr in this.table.Rows) {
                    if (dr.RowState == DataRowState.Deleted) 
                        continue;
                    if (!implementsINullable){
                        if (dr[this] == DBNull.Value){
                            throw ExceptionBuilder.NullKeyValues(ColumnName); 
                        }
                    } 
                    else{ 
                        if (DataStorage.IsObjectNull(dr[this])){
                            throw ExceptionBuilder.NullKeyValues(ColumnName); 
                        }
                    }
                }
            } 
       }
 
        internal void CheckNullable(DataRow row) { 
            if (!AllowDBNull) {
                Debug.Assert(null != _storage, "no storage"); 
                if (_storage.IsNull(row.GetDefaultRecord())) {
                   throw ExceptionBuilder.NullValues(ColumnName);
               }
            } 
        }
 
        protected void CheckUnique() { 
            if (!SortIndex.CheckUnique()) {
                // Throws an exception and the name of any column if its Unique property set to 
                // True and non-unique values are found in the column.
                throw ExceptionBuilder.NonUniqueValues(ColumnName);
            }
        } 

        internal int Compare(int record1, int record2) { 
            Debug.Assert(null != _storage, "null storage"); 
            return _storage.Compare(record1, record2);
        } 

        internal bool CompareValueTo(int record1, object value, bool checkType) {
            // this method is used to make sure value and exact type match.
            int valuesMatch = CompareValueTo(record1, value); 
            // if values match according to storage, do extra checks for exact compare
            if (valuesMatch == 0) { 
                Type leftType = value.GetType(); 
                Type rightType = _storage.Get(record1).GetType();
                // if strings, then do exact character by character check 
                if (leftType == typeof(System.String) && rightType == typeof(System.String)) {
                    return String.CompareOrdinal((string)_storage.Get(record1), (string)value) == 0 ? true : false;
                }
                // make sure same type 
                else if (leftType== rightType) {
                    return true; 
                } 
            }
            return false; 
        }

        internal int CompareValueTo(int record1, object value) {
            Debug.Assert(null != _storage, "null storage"); 
            return _storage.CompareValueTo(record1, value);
        } 
 
        internal object ConvertValue(object value) {
            Debug.Assert(null != _storage, "null storage"); 
            return _storage.ConvertValue(value);
        }

        internal void Copy(int srcRecordNo, int dstRecordNo) { 
            Debug.Assert(null != _storage, "null storage");
            _storage.Copy(srcRecordNo, dstRecordNo); 
        } 

        internal DataColumn Clone() { 
            DataColumn clone = (DataColumn) Activator.CreateInstance(this.GetType());
            // set All properties
//            clone.columnMapping = columnMapping;
 
            clone.SimpleType = SimpleType;
 
            clone.allowNull = allowNull; 
            clone.autoIncrement = autoIncrement;
            clone.autoIncrementStep = autoIncrementStep; 
            clone.autoIncrementSeed = autoIncrementSeed;
            clone.autoIncrementCurrent = autoIncrementCurrent;
            clone.caption = caption;
            clone.ColumnName = ColumnName; 
            clone._columnUri = _columnUri;
            clone._columnPrefix = _columnPrefix; 
            clone.DataType = DataType; 
            clone.defaultValue = defaultValue;
            clone.defaultValueIsNull = ((defaultValue == DBNull.Value)||(clone.ImplementsINullable && DataStorage.IsObjectSqlNull(defaultValue))) ? true:false; 
            clone.columnMapping = columnMapping;// clone column Mapping since we dont let MaxLength to be set throu API
            //
            clone.readOnly = readOnly;
            clone.MaxLength = MaxLength; 
            clone.dttype = dttype;
            clone._dateTimeMode = _dateTimeMode; 
 

            // so if we have set it, we should continue preserving the information 

            // ...Extended Properties
            if (this.extendedProperties != null) {
                foreach(Object key in this.extendedProperties.Keys) { 
                    clone.ExtendedProperties[key]=this.extendedProperties[key];
                } 
            } 

            return clone; 
        }

        /// 
        ///    Finds a relation that this column is the sole child of or null. 
        /// 
        internal DataRelation FindParentRelation() { 
            DataRelation[] parentRelations = new DataRelation[Table.ParentRelations.Count]; 
            Table.ParentRelations.CopyTo(parentRelations, 0);
 
            for (int i = 0; i < parentRelations.Length; i++) {
                DataRelation relation = parentRelations[i];
                DataKey key = relation.ChildKey;
                if (key.ColumnsReference.Length == 1 && key.ColumnsReference[0] == this) { 
                    return relation;
                } 
            } 
            // should we throw an exception?
            return null; 
        }


        internal object GetAggregateValue(int[] records, AggregateType kind) { 
            if (_storage == null) {
                if (kind == AggregateType.Count) 
                    return 0; 
                else
                    return DBNull.Value; 
                }
            return _storage.Aggregate(records, kind);
        }
 
        private int GetStringLength(int record) {
            Debug.Assert(null != _storage, "no storage"); 
            return _storage.GetStringLength(record); 
        }
 
        internal void Init(int record) {
            if (AutoIncrement) {
                object value = autoIncrementCurrent;
                autoIncrementCurrent += autoIncrementStep; 
                Debug.Assert(null != _storage, "no storage");
                _storage.Set(record, value); 
            } 
            else
                this[record] = defaultValue; 
        }

        internal static bool IsAutoIncrementType(Type dataType) {
            return((dataType == typeof(Int32)) || (dataType == typeof(Int64)) || (dataType == typeof(Int16)) || (dataType == typeof(Decimal)) || 
                   (dataType == typeof(SqlInt32)) || (dataType == typeof(SqlInt64)) || (dataType == typeof(SqlInt16)) || (dataType == typeof(SqlDecimal)));
        } 
 
        private bool IsColumnMappingValid(StorageType typeCode, MappingType mapping){
            if ((mapping != MappingType.Element) && DataStorage.IsTypeCustomType(typeCode)) { 
                return false;
            }
            return true;
        } 

        internal bool IsCustomType { 
            get { 
                if (null != _storage)
                    return _storage.IsCustomDefinedType; 
                return DataStorage.IsTypeCustomType(DataType);
            }
        }
 
        internal bool IsValueCustomTypeInstance(object value) {
            // if instance is not a storage supported type (built in or SQL types) 
            return (DataStorage.IsTypeCustomType(value.GetType()) && !(value is Type)); 
        }
 
        internal bool ImplementsIXMLSerializable {
            get {
                return implementsIXMLSerializable;
            } 
        }
 
        internal bool IsNull(int record) { 
            Debug.Assert(null != _storage, "no storage");
            return _storage.IsNull(record); 
        }

        /// 
        ///      Returns true if this column is a part of a Parent or Child key for a relation. 
        /// 
        internal bool IsInRelation() { 
            DataKey key; 
            DataRelationCollection rels = table.ParentRelations;
 
            Debug.Assert(rels != null, "Invalid ParentRelations");
            for (int i = 0; i < rels.Count; i++) {
                key = rels[i].ChildKey;
                Debug.Assert(key.HasValue, "Invalid child key (null)"); 
                if (key.ContainsColumn(this)) {
                    return true; 
                } 
            }
            rels = table.ChildRelations; 
            Debug.Assert(rels != null, "Invalid ChildRelations");
            for (int i = 0; i < rels.Count; i++) {
                key = rels[i].ParentKey;
                Debug.Assert(key.HasValue, "Invalid parent key (null)"); 
                if (key.ContainsColumn(this)) {
                    return true; 
                } 
            }
            return false; 
        }

        internal bool IsMaxLengthViolated() {
            if (MaxLength < 0) 
                return true;
 
            bool error = false; 
            object value;
            string errorText = null; 

            foreach(DataRow dr in Table.Rows){
                if (dr.HasVersion(DataRowVersion.Current)) {
                    value = dr[this]; 
                    if (!this.isSqlType) {
                        if (value != null && value != DBNull.Value && ((string)value).Length > MaxLength) { 
                            if (errorText == null) { 
                                errorText = ExceptionBuilder.MaxLengthViolationText(this.ColumnName);
                            } 
                            dr.RowError = errorText;
                            dr.SetColumnError(this, errorText);
                            error = true;
                        } 
                    }
                    else{ 
                        if (!DataStorage.IsObjectNull(value)&& ((SqlString)value).Value.Length > MaxLength) { 
                            if (errorText == null) {
                                errorText = ExceptionBuilder.MaxLengthViolationText(this.ColumnName); 
                            }
                            dr.RowError = errorText;
                            dr.SetColumnError(this, errorText);
                            error = true; 
                        }
                    } 
                } 
            }
            return error; 
        }

        internal bool IsNotAllowDBNullViolated() {//
            Index index = this.SortIndex; 
            DataRow[] rows = index.GetRows(index.FindRecords(DBNull.Value));
            for (int i = 0; i < rows.Length; i++) { 
                string errorText = ExceptionBuilder.NotAllowDBNullViolationText(this.ColumnName); 
                rows[i].RowError = errorText;
                rows[i].SetColumnError(this, errorText); 
            }
            return (rows.Length > 0);
        }
 
        internal void FinishInitInProgress () {
            if (this.Computed) 
                BindExpression(); 
        }
 
        protected virtual void OnPropertyChanging(PropertyChangedEventArgs pcevent) {
            if (onPropertyChangingDelegate != null)
                onPropertyChangingDelegate(this, pcevent);
        } 

        protected internal void RaisePropertyChanging(string name) { 
            OnPropertyChanging(new PropertyChangedEventArgs(name)); 
        }
 
        private void InsureStorage() {
            if (_storage == null) {
                _storage = DataStorage.CreateStorage(this, dataType);
            } 
        }
 
        internal void  SetCapacity(int capacity) { 
            InsureStorage();
            _storage.SetCapacity(capacity); 
        }

        private bool ShouldSerializeDefaultValue() {
            return (!DefaultValueIsNull); 
        }
 
        internal void OnSetDataSet() { 
        }
 
        // Returns the  of the column, if one exists.
        public override string ToString() {
            if (this.expression == null)
                return this.ColumnName; 
            else
                return this.ColumnName + " + " + this.Expression; 
 
        }
 

        internal object ConvertXmlToObject(string s) {
            Debug.Assert(s != null, "Caller is resposible for missing element/attribure case");
            InsureStorage(); 
            return _storage.ConvertXmlToObject(s);
        } 
 
        internal object ConvertXmlToObject( XmlReader xmlReader, XmlRootAttribute xmlAttrib) {
            InsureStorage(); 
            return _storage.ConvertXmlToObject(xmlReader, xmlAttrib);
        }

 
        internal string ConvertObjectToXml(object value) {
            Debug.Assert(value != null && (value != DBNull.Value), "Caller is resposible for checking on DBNull"); 
            InsureStorage(); 
            return _storage.ConvertObjectToXml(value);
        } 

        internal void ConvertObjectToXml(object value, XmlWriter xmlWriter, XmlRootAttribute xmlAttrib) {
            Debug.Assert(value != null && (value != DBNull.Value), "Caller is resposible for checking on DBNull");
            InsureStorage(); 
            _storage.ConvertObjectToXml(value, xmlWriter, xmlAttrib);
        } 
 
        internal object GetEmptyColumnStore(int recordCount) {
            InsureStorage(); 
            return _storage.GetEmptyStorageInternal(recordCount);
        }

        internal void CopyValueIntoStore(int record, object store, BitArray nullbits, int storeIndex) { 
            Debug.Assert(null != _storage, "no storage");
            _storage.CopyValueInternal(record, store, nullbits, storeIndex); 
        } 

        internal void SetStorage(object store, BitArray nullbits) { 
            InsureStorage();
            _storage.SetStorageInternal(store, nullbits);
        }
 
        internal void AddDependentColumn(DataColumn expressionColumn) {
            if (dependentColumns == null) { 
                dependentColumns = new List(); 
            }
            Debug.Assert(!dependentColumns.Contains(expressionColumn), "duplicate column - expected to be unique"); 
            dependentColumns.Add(expressionColumn);
            this.table.AddDependentColumn(expressionColumn);
        }
 
        internal void RemoveDependentColumn(DataColumn expressionColumn) {
            if (dependentColumns != null && dependentColumns.Contains(expressionColumn)) { 
                dependentColumns.Remove(expressionColumn); 
            }
            this.table.RemoveDependentColumn(expressionColumn); 
        }

        internal void HandleDependentColumnList(DataExpression oldExpression, DataExpression newExpression) {
            DataColumn[] dependency; 
            // remove this column from the dependentColumn list of the columns this column depends on.
            if (oldExpression != null) { 
                dependency = oldExpression.GetDependency(); 
                foreach(DataColumn col in dependency) {
                    Debug.Assert(null != col, "null datacolumn in expression dependencies"); 
                    col.RemoveDependentColumn(this);
                    if (col.table != this.table) {
                        this.table.RemoveDependentColumn(this);
                    } 
                }
                this.table.RemoveDependentColumn(this); 
            } 

            if (newExpression != null) { 
                // get the list of columns that this expression depends on
                dependency = newExpression.GetDependency();
                // add this column to dependent column list of each column this column depends on
                foreach(DataColumn col in dependency) { 
                    col.AddDependentColumn(this);
                    if (col.table != this.table) { 
                        this.table.AddDependentColumn(this); 
                    }
                } 
                this.table.AddDependentColumn(this);
            }
        }
    } 
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.

                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK