LinqDataSourceView.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ DotNET / DotNET / 8.0 / untmp / Orcas / RTM / ndp / fx / src / xsp / System / Web / Extensions / ui / webcontrols / LinqDataSourceView.cs / 2 / LinqDataSourceView.cs

                            //------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
//----------------------------------------------------------------------------- 

namespace System.Web.UI.WebControls { 
    using System; 
    using System.Collections;
    using System.Collections.Generic; 
    using System.Collections.ObjectModel;
    using System.Collections.Specialized;
    using System.ComponentModel;
    using System.Data.Linq; 
    using System.Data.Linq.Mapping;
    using System.Diagnostics.CodeAnalysis; 
    using System.Globalization; 
    using System.Linq;
    using System.Reflection; 
    using System.Security.Permissions;
    using System.Text;
    using System.Text.RegularExpressions;
    using System.Web; 
    using System.Web.Compilation;
    using System.Web.Query.Dynamic; 
    using System.Web.Resources; 

    [AspNetHostingPermission(SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)] 
    [AspNetHostingPermission(SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
    public class LinqDataSourceView : DataSourceView, IStateManager {

        // This regular expression verifies that parameter names are set to valid identifiers.  This validation 
        // needs to match the parser's identifier validation as done in the default block of NextToken().
        private static readonly string _identifierPattern = 
            @"^\s*[\p{Lu}\p{Ll}\p{Lt}\p{Lm}\p{Lo}\p{Nl}_]" +                           // first character 
            @"[\p{Lu}\p{Ll}\p{Lt}\p{Lm}\p{Lo}\p{Nl}\p{Nd}\p{Pc}\p{Mn}\p{Mc}\p{Cf}_]*"; // remaining characters
 
        private static readonly Regex _identifierRegex = new Regex(_identifierPattern + @"\s*$");

        private static readonly Regex _autoGenerateOrderByRegex = new Regex(_identifierPattern +
            @"(\s+(asc|ascending|desc|descending))?\s*$", RegexOptions.IgnoreCase);     // order operators 

        private static readonly object EventContextCreated = new object(); 
        private static readonly object EventContextCreating = new object(); 
        private static readonly object EventContextDisposing = new object();
        private static readonly object EventDeleted = new object(); 
        private static readonly object EventDeleting = new object();
        private static readonly object EventInserted = new object();
        private static readonly object EventInserting = new object();
        private static readonly object EventSelected = new object(); 
        private static readonly object EventSelecting = new object();
        private static readonly object EventUpdated = new object(); 
        private static readonly object EventUpdating = new object(); 

        private HttpContext _context; 
        private LinqDataSource _owner;
        private bool _tracking;

        private bool _autoGenerateOrderByClause = false; 
        private bool _autoGenerateWhereClause = false;
        private bool _autoPage = true; 
        private bool _autoSort = true; 
        private string _contextTypeName;
        private object _dataContext; 
        private ParameterCollection _deleteParameters;
        private IDynamicQueryable _dynamicQueryable;
        private bool _enableDelete = false;
        private bool _enableInsert = false; 
        private bool _enableUpdate = false;
        private string _groupBy; 
        private ParameterCollection _groupByParameters; 
        private ParameterCollection _insertParameters;
        private ILinqToSql _linqToSql; 
        private string _orderBy;
        private ParameterCollection _orderByParameters;
        private string _orderGroupsBy;
        private ParameterCollection _orderGroupsByParameters; 
        // using Hashtable for original values so that ObjectStateFormatter will serialize it properly in ViewState.
        private Hashtable _originalValues; 
        private string _selectNew; 
        private ParameterCollection _selectNewParameters;
        private bool _storeOriginalValuesInViewState = true; 
        private object _table;
        private string _tableName;
        private ParameterCollection _updateParameters;
        private string _where; 
        private ParameterCollection _whereParameters;
 
        public LinqDataSourceView(LinqDataSource owner, string name, HttpContext context) 
            : this(owner, name, context, new DynamicQueryableWrapper(), new LinqToSqlWrapper()) {
        } 

        // internal constructor that takes mocks for unit tests.
        internal LinqDataSourceView(LinqDataSource owner, string name, HttpContext context,
                                    IDynamicQueryable dynamicQueryable, ILinqToSql linqToSql) : base(owner, name) { 
            _owner = owner;
            _context = context; 
            _dynamicQueryable = dynamicQueryable; 
            _linqToSql = linqToSql;
        } 

        public bool AutoGenerateOrderByClause {
            get {
                return _autoGenerateOrderByClause; 
            }
            set { 
                if (_autoGenerateOrderByClause != value) { 
                    _autoGenerateOrderByClause = value;
                    OnDataSourceViewChanged(EventArgs.Empty); 
                }
            }
        }
 
        public bool AutoGenerateWhereClause {
            get { 
                return _autoGenerateWhereClause; 
            }
            set { 
                if (_autoGenerateWhereClause != value) {
                    _autoGenerateWhereClause = value;
                    OnDataSourceViewChanged(EventArgs.Empty);
                } 
            }
        } 
 
        public bool AutoPage {
            get { 
                return _autoPage;
            }
            set {
                if (_autoPage != value) { 
                    _autoPage = value;
                    OnDataSourceViewChanged(EventArgs.Empty); 
                } 
            }
        } 

        public bool AutoSort {
            get {
                return _autoSort; 
            }
            set { 
                if (_autoSort != value) { 
                    _autoSort = value;
                    OnDataSourceViewChanged(EventArgs.Empty); 
                }
            }
        }
 
        public override bool CanDelete {
            get { 
                return EnableDelete; 
            }
        } 

        public override bool CanInsert {
            get {
                return EnableInsert; 
            }
        } 
 
        // When AutoPage is false the user should manually page in the Selecting event.
        public override bool CanPage { 
            get {
                return true;
            }
        } 

        // When AutoPage is false the user must set the total row count in the Selecting event. 
        public override bool CanRetrieveTotalRowCount { 
            get {
                return true; 
            }
        }

        // When AutoSort is false the user should manually sort in the Selecting event. 
        public override bool CanSort {
            get { 
                return true; 
            }
        } 

        public override bool CanUpdate {
            get {
                return EnableUpdate; 
            }
        } 
 
        private bool ContextAndTableCreated {
            get { 
                // After context creation the data context can be null if the table is a static
                // member and the table can be null if a ContextCreated exception was handled.
                return (_dataContext != null) || (_table != null);
            } 
        }
 
        protected virtual Type ContextType { 
            get {
                string typeName = ContextTypeName; 
                if (String.IsNullOrEmpty(typeName)) {
                    throw new InvalidOperationException(String.Format(CultureInfo.InvariantCulture,
                        AtlasWeb.LinqDataSourceView_ContextTypeNameNotSpecified, _owner.ID));
                } 
                try {
                    return BuildManager.GetType(typeName, /*throwOnFail*/true, /*ignoreCase*/true); 
                } 
                catch (Exception e) {
                    throw new InvalidOperationException(String.Format(CultureInfo.InvariantCulture, 
                        AtlasWeb.LinqDataSourceView_ContextTypeNameNotFound, _owner.ID), e);
                }
            }
        } 

        public virtual string ContextTypeName { 
            get { 
                return _contextTypeName ?? String.Empty;
            } 
            set {
                if (_contextTypeName != value) {
                    if (ContextAndTableCreated) {
                        throw new InvalidOperationException(String.Format(CultureInfo.InvariantCulture, 
                            AtlasWeb.LinqDataSourceView_ContextTypeNameChanged, _owner.ID));
                    } 
                    _contextTypeName = value; 
                    OnDataSourceViewChanged(EventArgs.Empty);
                } 
            }
        }

        public ParameterCollection DeleteParameters { 
            get {
                if (_deleteParameters == null) { 
                    _deleteParameters = new ParameterCollection(); 
                }
                return _deleteParameters; 
            }
        }

        public bool EnableDelete { 
            get {
                return _enableDelete; 
            } 
            set {
                if (_enableDelete != value) { 
                    _enableDelete = value;
                    OnDataSourceViewChanged(EventArgs.Empty);
                }
            } 
        }
 
        public bool EnableInsert { 
            get {
                return _enableInsert; 
            }
            set {
                if (_enableInsert != value) {
                    _enableInsert = value; 
                    OnDataSourceViewChanged(EventArgs.Empty);
                } 
            } 
        }
 
        public bool EnableUpdate {
            get {
                return _enableUpdate;
            } 
            set {
                if (_enableUpdate != value) { 
                    _enableUpdate = value; 
                    OnDataSourceViewChanged(EventArgs.Empty);
                } 
            }
        }

        public string GroupBy { 
            get {
                return _groupBy ?? String.Empty; 
            } 
            set {
                if (_groupBy != value) { 
                    _groupBy = value;
                    OnDataSourceViewChanged(EventArgs.Empty);
                }
            } 
        }
 
        public ParameterCollection GroupByParameters { 
            get {
                if (_groupByParameters == null) { 
                    _groupByParameters = new ParameterCollection();
                    _groupByParameters.ParametersChanged += new EventHandler(SelectParametersChangedEventHandler);
                    if (_tracking) {
                        ((IStateManager)_groupByParameters).TrackViewState(); 
                    }
                } 
                return _groupByParameters; 
            }
        } 

        public ParameterCollection InsertParameters {
            get {
                if (_insertParameters == null) { 
                    _insertParameters = new ParameterCollection();
                } 
                return _insertParameters; 
            }
        } 

        protected bool IsTrackingViewState {
            get {
                return _tracking; 
            }
        } 
 
        public string OrderBy {
            get { 
                return _orderBy ?? String.Empty;
            }
            set {
                if (_orderBy != value) { 
                    _orderBy = value;
                    OnDataSourceViewChanged(EventArgs.Empty); 
                } 
            }
        } 

        public ParameterCollection OrderByParameters {
            get {
                if (_orderByParameters == null) { 
                    _orderByParameters = new ParameterCollection();
                    _orderByParameters.ParametersChanged += new EventHandler(SelectParametersChangedEventHandler); 
                    if (_tracking) { 
                        ((IStateManager)_orderByParameters).TrackViewState();
                    } 
                }
                return _orderByParameters;
            }
        } 

        public string OrderGroupsBy { 
            get { 
                return _orderGroupsBy ?? String.Empty;
            } 
            set {
                if (_orderGroupsBy != value) {
                    _orderGroupsBy = value;
                    OnDataSourceViewChanged(EventArgs.Empty); 
                }
            } 
        } 

        public ParameterCollection OrderGroupsByParameters { 
            get {
                if (_orderGroupsByParameters == null) {
                    _orderGroupsByParameters = new ParameterCollection();
                    _orderGroupsByParameters.ParametersChanged += new EventHandler(SelectParametersChangedEventHandler); 
                    if (_tracking) {
                        ((IStateManager)_orderGroupsByParameters).TrackViewState(); 
                    } 
                }
                return _orderGroupsByParameters; 
            }
        }

        // Named SelectNew on the View instead of Select due to naming conflicts with the Select method. 
        public string SelectNew {
            get { 
                return _selectNew ?? String.Empty; 
            }
            set { 
                if (_selectNew != value) {
                    _selectNew = value;
                    OnDataSourceViewChanged(EventArgs.Empty);
                } 
            }
        } 
 
        public ParameterCollection SelectNewParameters {
            get { 
                if (_selectNewParameters == null) {
                    _selectNewParameters = new ParameterCollection();
                    _selectNewParameters.ParametersChanged += new EventHandler(SelectParametersChangedEventHandler);
                    if (_tracking) { 
                        ((IStateManager)_selectNewParameters).TrackViewState();
                    } 
                } 
                return _selectNewParameters;
            } 
        }

        public bool StoreOriginalValuesInViewState {
            get { 
                return _storeOriginalValuesInViewState;
            } 
            set { 
                if (_storeOriginalValuesInViewState != value) {
                    _storeOriginalValuesInViewState = value; 
                    OnDataSourceViewChanged(EventArgs.Empty);
                }
            }
        } 

        public string TableName { 
            get { 
                return _tableName ?? String.Empty;
            } 
            set {
                if (_tableName != value) {
                    if (ContextAndTableCreated) {
                        throw new InvalidOperationException(String.Format(CultureInfo.InvariantCulture, 
                            AtlasWeb.LinqDataSourceView_TableNameChanged, _owner.ID));
                    } 
                    _tableName = value; 
                    OnDataSourceViewChanged(EventArgs.Empty);
                } 
            }
        }

        public ParameterCollection UpdateParameters { 
            get {
                if (_updateParameters == null) { 
                    _updateParameters = new ParameterCollection(); 
                }
                return _updateParameters; 
            }
        }

        public string Where { 
            get {
                return _where ?? String.Empty; 
            } 
            set {
                if (_where != value) { 
                    _where = value;
                    OnDataSourceViewChanged(EventArgs.Empty);
                }
            } 
        }
 
        public ParameterCollection WhereParameters { 
            get {
                if (_whereParameters == null) { 
                    _whereParameters = new ParameterCollection();
                    _whereParameters.ParametersChanged += new EventHandler(SelectParametersChangedEventHandler);
                    if (_tracking) {
                        ((IStateManager)_whereParameters).TrackViewState(); 
                    }
                } 
                return _whereParameters; 
            }
        } 

        public event EventHandler ContextCreated {
            add {
                Events.AddHandler(EventContextCreated, value); 
            }
            remove { 
                Events.RemoveHandler(EventContextCreated, value); 
            }
        } 

        public event EventHandler ContextCreating {
            add {
                Events.AddHandler(EventContextCreating, value); 
            }
            remove { 
                Events.RemoveHandler(EventContextCreating, value); 
            }
        } 

        public event EventHandler ContextDisposing {
            add {
                Events.AddHandler(EventContextDisposing, value); 
            }
            remove { 
                Events.RemoveHandler(EventContextDisposing, value); 
            }
        } 

        public event EventHandler Deleted {
            add {
                Events.AddHandler(EventDeleted, value); 
            }
            remove { 
                Events.RemoveHandler(EventDeleted, value); 
            }
        } 

        public event EventHandler Deleting {
            add {
                Events.AddHandler(EventDeleting, value); 
            }
            remove { 
                Events.RemoveHandler(EventDeleting, value); 
            }
        } 

        public event EventHandler Inserted {
            add {
                Events.AddHandler(EventInserted, value); 
            }
            remove { 
                Events.RemoveHandler(EventInserted, value); 
            }
        } 

        public event EventHandler Inserting {
            add {
                Events.AddHandler(EventInserting, value); 
            }
            remove { 
                Events.RemoveHandler(EventInserting, value); 
            }
        } 

        public event EventHandler Selected {
            add {
                Events.AddHandler(EventSelected, value); 
            }
            remove { 
                Events.RemoveHandler(EventSelected, value); 
            }
        } 

        public event EventHandler Selecting {
            add {
                Events.AddHandler(EventSelecting, value); 
            }
            remove { 
                Events.RemoveHandler(EventSelecting, value); 
            }
        } 

        public event EventHandler Updated {
            add {
                Events.AddHandler(EventUpdated, value); 
            }
            remove { 
                Events.RemoveHandler(EventUpdated, value); 
            }
        } 

        public event EventHandler Updating {
            add {
                Events.AddHandler(EventUpdating, value); 
            }
            remove { 
                Events.RemoveHandler(EventUpdating, value); 
            }
        } 

        private static IQueryable AsQueryable(object o) {
            IQueryable oQueryable = o as IQueryable;
            if (oQueryable != null) { 
                return oQueryable;
            } 
 
            // Wrap strings in IEnumerable instead of treating as IEnumerable.
            string oString = o as string; 
            if (oString != null) {
                return Queryable.AsQueryable(new string[] { oString });
            }
 
            IEnumerable oEnumerable = o as IEnumerable;
            if (oEnumerable != null) { 
                // IEnumerable can be directly converted to an IQueryable. 
                Type genericType = LinqDataSourceHelper.FindGenericEnumerableType(o.GetType());
                if (genericType != null) { 
                    // The non-generic Queryable.AsQueryable gets called for array types, executing
                    // the FindGenericType logic again.  Might want to investigate way to avoid this.
                    return Queryable.AsQueryable(oEnumerable);
                } 
                // Wrap non-generic IEnumerables in IEnumerable.
                List genericList = new List(); 
                foreach (object item in oEnumerable) { 
                    genericList.Add(item);
                } 
                return Queryable.AsQueryable(genericList);
            }

            // Wrap non-IEnumerable types in IEnumerable. 
            Type listType = typeof(List<>).MakeGenericType(o.GetType());
            IList list = (IList)CreateObjectInstance(listType); 
            list.Add(o); 
            return Queryable.AsQueryable(list);
        } 

        private object BuildDataObject(Type dataObjectType, IDictionary inputParameters) {
            object dataObject = CreateObjectInstance(dataObjectType);
 
            Dictionary convertOrValidateExceptions = null;
            PropertyDescriptorCollection props = TypeDescriptor.GetProperties(dataObject); 
            foreach (DictionaryEntry de in inputParameters) { 
                string propName = (de.Key == null ? String.Empty : de.Key.ToString());
                PropertyDescriptor property = props.Find(propName, /*ignoreCase*/true); 
                // NOTE: No longer throws when a property is not found or is read only.  This makes
                // Delete, Insert and Update operations more optimistic, allowing scenarios such as:
                // 1) Deletes and Updates after projecting data in the Selecting event.
                // 2) Deletes and Updates after selecting children of the data object type in the 
                //    Selecting event.
                if ((property != null) && (!property.IsReadOnly)) { 
                    try { 
                        object value = BuildObjectValue(de.Value, property.PropertyType, propName);
                        property.SetValue(dataObject, value); 
                    }
                    catch (Exception e) {
                        if (convertOrValidateExceptions == null) {
                            convertOrValidateExceptions = new Dictionary( 
                                StringComparer.OrdinalIgnoreCase);
                        } 
                        convertOrValidateExceptions[property.Name] = e; 
                    }
                } 
            }

            // package up conversion or dlinq validation exceptions into single exception.
            if (convertOrValidateExceptions != null) { 
                throw new LinqDataSourceValidationException(String.Format(CultureInfo.InvariantCulture,
                    AtlasWeb.LinqDataSourceView_ValidationFailed, dataObjectType), convertOrValidateExceptions); 
            } 

            return dataObject; 
        }

        private LinqDataSourceEditData BuildDeleteDataObject(object table, IDictionary keys, IDictionary oldValues) {
            Type dataObjectType = GetDataObjectType(table.GetType()); 
            IDictionary caseInsensitiveOldValues = new OrderedDictionary(StringComparer.OrdinalIgnoreCase);
            IDictionary originalValues = GetOriginalValues(keys); 
 
            ParameterCollection deleteParameters = DeleteParameters;
            MergeDictionaries(dataObjectType, deleteParameters, keys, caseInsensitiveOldValues); 
            MergeDictionaries(dataObjectType, deleteParameters, oldValues, caseInsensitiveOldValues);
            if (originalValues != null) {
                MergeDictionaries(dataObjectType, deleteParameters, originalValues, caseInsensitiveOldValues);
            } 

            LinqDataSourceEditData editData = new LinqDataSourceEditData(); 
            editData.OriginalDataObject = BuildDataObject(dataObjectType, caseInsensitiveOldValues); 
            return editData;
        } 

        private LinqDataSourceEditData BuildInsertDataObject(object table, IDictionary values) {
            Type dataObjectType = GetDataObjectType(table.GetType());
            IDictionary caseInsensitiveNewValues = new OrderedDictionary(StringComparer.OrdinalIgnoreCase); 
            MergeDictionaries(dataObjectType, InsertParameters, values, caseInsensitiveNewValues);
 
            LinqDataSourceEditData editData = new LinqDataSourceEditData(); 
            editData.NewDataObject = BuildDataObject(dataObjectType, caseInsensitiveNewValues);
            return editData; 
        }

        private static object BuildObjectValue(object value, Type destinationType, string paramName) {
            // NOTE: This method came from ObjectDataSource with no changes made. 
            // Only consider converting the type if the value is non-null and the types don't match
            if ((value != null) && (!destinationType.IsInstanceOfType(value))) { 
                Type innerDestinationType = destinationType; 
                bool isNullable = false;
                if (destinationType.IsGenericType && 
                    (destinationType.GetGenericTypeDefinition() == typeof(Nullable<>))) {
                    innerDestinationType = destinationType.GetGenericArguments()[0];
                    isNullable = true;
                } 
                else {
                    if (destinationType.IsByRef) { 
                        innerDestinationType = destinationType.GetElementType(); 
                    }
                } 

                // Try to convert from for example string to DateTime, so that
                // afterwards we can convert DateTime to Nullable
 
                // If the value is a string, we attempt to use a TypeConverter to convert it
                value = ConvertType(value, innerDestinationType, paramName); 
 
                // Special-case the value when the destination is Nullable
                if (isNullable) { 
                    Type paramValueType = value.GetType();
                    if (innerDestinationType != paramValueType) {
                        // Throw if for example, we are trying to convert from int to Nullable
                        throw new InvalidOperationException(String.Format(CultureInfo.InvariantCulture, 
                            AtlasWeb.LinqDataSourceView_CannotConvertType, paramName, paramValueType.FullName,
                            String.Format(CultureInfo.InvariantCulture, "Nullable<{0}>", 
                            destinationType.GetGenericArguments()[0].FullName))); 
                    }
                } 
            }
            return value;
        }
 
        private LinqDataSourceEditData BuildUpdateDataObjects(object table, IDictionary keys,
                                                              IDictionary values, IDictionary oldValues) { 
            Type dataObjectType = GetDataObjectType(table.GetType()); 
            IDictionary caseInsensitiveNewValues = new OrderedDictionary(StringComparer.OrdinalIgnoreCase);
            IDictionary caseInsensitiveOldValues = new OrderedDictionary(StringComparer.OrdinalIgnoreCase); 
            IDictionary originalValues = GetOriginalValues(keys);

            // We start out with the old values, just to pre-populate the list with items
            // that might not have corresponding new values. For example if a GridView has 
            // a read-only field, there will be an old value, but no new value. The data object
            // still has to have *some* value for a given field, so we just use the old value. 
            ParameterCollection updateParameters = UpdateParameters; 
            MergeDictionaries(dataObjectType, updateParameters, oldValues, caseInsensitiveOldValues, caseInsensitiveNewValues);
            MergeDictionaries(dataObjectType, updateParameters, keys, caseInsensitiveOldValues, caseInsensitiveNewValues); 
            if (originalValues != null) {
                MergeDictionaries(dataObjectType, updateParameters, originalValues, caseInsensitiveOldValues, caseInsensitiveNewValues);
            }
            MergeDictionaries(dataObjectType, updateParameters, values, caseInsensitiveNewValues); 

            LinqDataSourceEditData editData = new LinqDataSourceEditData(); 
            editData.NewDataObject = BuildDataObject(dataObjectType, caseInsensitiveNewValues); 
            editData.OriginalDataObject = BuildDataObject(dataObjectType, caseInsensitiveOldValues);
            return editData; 
        }

        private static object ConvertType(object value, Type type, string paramName) {
            // NOTE: This method came from ObjectDataSource with no changes made. 
            string s = value as string;
            if (s != null) { 
                // Get the type converter for the destination type 
                TypeConverter converter = TypeDescriptor.GetConverter(type);
                if (converter != null) { 
                    // Perform the conversion
                    try {
                        value = converter.ConvertFromString(s);
                    } 
                    catch (NotSupportedException) {
                        throw new InvalidOperationException(String.Format(CultureInfo.InvariantCulture, 
                            AtlasWeb.LinqDataSourceView_CannotConvertType, paramName, typeof(string).FullName, 
                            type.FullName));
                    } 
                    catch (FormatException) {
                        throw new InvalidOperationException(String.Format(CultureInfo.InvariantCulture,
                            AtlasWeb.LinqDataSourceView_CannotConvertType, paramName, typeof(string).FullName,
                            type.FullName)); 
                    }
                } 
            } 
            return value;
        } 

        protected virtual object CreateContext(Type contextType) {
            object context = CreateObjectInstance(contextType);
            // disable object tracking for read-only data contexts created by LinqDataSource. 
            if (!(CanDelete || CanInsert || CanUpdate)) {
                DataContext dataContext = context as DataContext; 
                if (dataContext != null) { 
                    dataContext.ObjectTrackingEnabled = false;
                } 
            }
            return context;
        }
 
        private void CreateContextAndTable() {
            bool eventFired = false; 
            try { 
                LinqDataSourceContextEventArgs contextEventArgs = new LinqDataSourceContextEventArgs();
                OnContextCreating(contextEventArgs); 

                _dataContext = contextEventArgs.ObjectInstance;
                Type contextType = null;
                MemberInfo tableMemberInfo = null; 
                if (_dataContext == null) {
                    // construct the context unless accessing a static table for Select. 
                    contextType = ContextType; 
                    tableMemberInfo = GetTableMemberInfo(contextType);
                    if (tableMemberInfo != null) { 
                        if (!MemberIsStatic(tableMemberInfo)) {
                            _dataContext = CreateContext(contextType);
                        }
                    } 
                }
                else { 
                    // use the manually constructed context. 
                    tableMemberInfo = GetTableMemberInfo(_dataContext.GetType());
                } 

                // fetch the table from the context.
                if (tableMemberInfo != null) {
                    FieldInfo field = tableMemberInfo as FieldInfo; 
                    if (field != null) {
                        _table = field.GetValue(_dataContext); 
                    } 
                    PropertyInfo property = tableMemberInfo as PropertyInfo;
                    if (property != null) { 
                        _table = property.GetValue(_dataContext, null);
                    }
                }
                if (_table == null) { 
                    throw new InvalidOperationException(String.Format(CultureInfo.InvariantCulture,
                        AtlasWeb.LinqDataSourceView_TableNameNotFound, TableName, contextType.Name, _owner.ID)); 
                } 
            }
            catch (Exception e) { 
                eventFired = true;
                LinqDataSourceStatusEventArgs createdEventArgs = new LinqDataSourceStatusEventArgs(e);
                OnContextCreated(createdEventArgs);
                // GetTable only returns null if the ContextCreated exception is handled. 
                if (!createdEventArgs.ExceptionHandled) {
                    throw; 
                } 
            }
            finally { 
                if (!eventFired) {
                    LinqDataSourceStatusEventArgs createdEventArgs = new LinqDataSourceStatusEventArgs(_dataContext);
                    OnContextCreated(createdEventArgs);
                } 
            }
        } 
 
        private static object CreateObjectInstance(Type type) {
            // FastCreatePublicInstance is faster than Activator.CreateInstance since it caches the type factories. 
            return HttpRuntime.FastCreatePublicInstance(type);
        }

        public int Delete(IDictionary keys, IDictionary oldValues) { 
            return ExecuteDelete(keys, oldValues);
        } 
 
        [SuppressMessage("Microsoft.Naming", "CA1720:AvoidTypeNamesInParameters", MessageId = "2#",
            Justification = "Names are consistent with those used in the ObjectDataSource classes")] 
        protected virtual void DeleteDataObject(object dataContext, object table, object oldDataObject) {
            _linqToSql.Attach((ITable)table, oldDataObject);
            _linqToSql.Remove((ITable)table, oldDataObject);
            _linqToSql.SubmitChanges((DataContext)dataContext); 
        }
 
        private void EnsureContextAndTable(bool selecting) { 
            if (!ContextAndTableCreated) {
                CreateContextAndTable(); 
            }
            if (_dataContext != null) {
                ValidateContextType(_dataContext.GetType(), selecting);
            } 
            if (_table != null) {
                ValidateTableType(_table.GetType(), selecting); 
            } 
        }
 
        private IDictionary EscapeParameterKeys(IDictionary parameters) {
            Dictionary escapedParameters = new Dictionary(parameters.Count,
                StringComparer.OrdinalIgnoreCase);
            foreach (KeyValuePair parameter in parameters) { 
                string key = parameter.Key;
                if (String.IsNullOrEmpty(key)) { 
                    throw new InvalidOperationException(String.Format(CultureInfo.InvariantCulture, 
                        AtlasWeb.LinqDataSourceView_ParametersMustBeNamed, _owner.ID));
                } 
                ValidateParameterName(key);
                escapedParameters.Add('@' + key, parameter.Value);
            }
            return escapedParameters; 
        }
 
        protected override int ExecuteDelete(IDictionary keys, IDictionary oldValues) { 
            ValidateDeleteSupported(keys, oldValues);
            EnsureContextAndTable(false); 

            if (_table != null) {
                LinqDataSourceEditData editData = null;
                LinqDataSourceDeleteEventArgs deleteEventArgs = null; 
                try {
                    editData = BuildDeleteDataObject(_table, keys, oldValues); 
                } 
                catch (LinqDataSourceValidationException e) {
                    // allow user to handle conversion or dlinq property validation exceptions. 
                    deleteEventArgs = new LinqDataSourceDeleteEventArgs(e);
                    OnDeleting(deleteEventArgs);
                    if (deleteEventArgs.ExceptionHandled) {
                        return -1; 
                    }
                    throw; 
                } 
                deleteEventArgs = new LinqDataSourceDeleteEventArgs(editData.OriginalDataObject);
                OnDeleting(deleteEventArgs); 
                if (deleteEventArgs.Cancel) {
                    return -1;
                }
 
                LinqDataSourceStatusEventArgs deletedEventArgs = null;
                try { 
                    DeleteDataObject(_dataContext, _table, deleteEventArgs.OriginalObject); 
                }
                catch (Exception e) { 
                    // allow user to handle dlinq exceptions including OnValidate validation.
                    deletedEventArgs = new LinqDataSourceStatusEventArgs(e);
                    OnDeleted(deletedEventArgs);
                    if (deletedEventArgs.ExceptionHandled) { 
                        return -1;
                    } 
                    throw; 
                }
                deletedEventArgs = new LinqDataSourceStatusEventArgs(deleteEventArgs.OriginalObject); 
                OnDeleted(deletedEventArgs);
            }
            // estimated number of rows deleted.
            return 1; 
        }
 
        protected override int ExecuteInsert(IDictionary values) { 
            ValidateInsertSupported(values);
            EnsureContextAndTable(false); 

            if (_table != null) {
                LinqDataSourceEditData editData = null;
                LinqDataSourceInsertEventArgs insertEventArgs = null; 
                try {
                    editData = BuildInsertDataObject(_table, values); 
                } 
                catch (LinqDataSourceValidationException e) {
                    // allow user to handle conversion or dlinq property validation exceptions. 
                    insertEventArgs = new LinqDataSourceInsertEventArgs(e);
                    OnInserting(insertEventArgs);
                    if (insertEventArgs.ExceptionHandled) {
                        return -1; 
                    }
                    throw; 
                } 
                insertEventArgs = new LinqDataSourceInsertEventArgs(editData.NewDataObject);
                OnInserting(insertEventArgs); 
                if (insertEventArgs.Cancel) {
                    return -1;
                }
 
                LinqDataSourceStatusEventArgs insertedEventArgs = null;
                try { 
                    InsertDataObject(_dataContext, _table, insertEventArgs.NewObject); 
                }
                catch (Exception e) { 
                    // allow user to handle dlinq exceptions including OnValidate validation.
                    insertedEventArgs = new LinqDataSourceStatusEventArgs(e);
                    OnInserted(insertedEventArgs);
                    if (insertedEventArgs.ExceptionHandled) { 
                        return -1;
                    } 
                    throw; 
                }
                insertedEventArgs = new LinqDataSourceStatusEventArgs(insertEventArgs.NewObject); 
                OnInserted(insertedEventArgs);
            }
            // estimated number of rows inserted.
            return 1; 
        }
 
        protected internal override IEnumerable ExecuteSelect(DataSourceSelectArguments arguments) { 
            if (arguments == null) {
                throw new ArgumentNullException("arguments"); 
            }

            _originalValues = null;
            IDictionary whereParameters = GetParameterValues(WhereParameters); 
            IOrderedDictionary orderByParameters = GetOrderedParameterValues(OrderByParameters);
            IDictionary groupByParameters = GetParameterValues(GroupByParameters); 
            IDictionary orderGroupsByParameters = GetParameterValues(OrderGroupsByParameters); 
            IDictionary selectNewParameters = GetParameterValues(SelectNewParameters);
 
            LinqDataSourceSelectEventArgs selectEventArgs = new LinqDataSourceSelectEventArgs(arguments,
                whereParameters, orderByParameters, groupByParameters, orderGroupsByParameters, selectNewParameters);
            OnSelecting(selectEventArgs);
            if (selectEventArgs.Cancel) { 
                return null;
            } 
 
            object selectResult = selectEventArgs.Result;
            object table = selectResult; 

            // Original values should only be stored for valid delete and update scenarios.
            bool storeOriginalValues = StoreOriginalValuesInViewState && (CanDelete || CanUpdate) &&
                String.IsNullOrEmpty(GroupBy) && String.IsNullOrEmpty(SelectNew); 

            if (selectResult == null) { 
                EnsureContextAndTable(true); 
                selectResult = _table;
                table = _table; 
            }
            // If the provided select result was not a DLinq table and we need to store
            // original values then we must get the table and create a new data context
            // instance so that we can access the column metadata. 
            else if (!(table is ITable) && storeOriginalValues) {
                EnsureContextAndTable(true); 
                table = _table; 
            }
 
            return ExecuteSelectQuery(selectEventArgs, selectResult, table, storeOriginalValues);
        }

        private IQueryable ExecuteSelectAutoSortAndPage(IQueryable source, DataSourceSelectArguments arguments) { 
            IQueryable result = source;
            string sortExpression = arguments.SortExpression; 
            if (AutoSort && (!String.IsNullOrEmpty(sortExpression))) { 
                result = _dynamicQueryable.OrderBy(result, sortExpression);
            } 
            if (AutoPage) {
                if (arguments.RetrieveTotalRowCount) {
                    arguments.TotalRowCount = _dynamicQueryable.Count(result);
                } 
                if ((arguments.MaximumRows > 0) && (arguments.StartRowIndex >= 0)) {
                    result = _dynamicQueryable.Skip(result, arguments.StartRowIndex); 
                    result = _dynamicQueryable.Take(result, arguments.MaximumRows); 
                }
            } 
            else if (arguments.RetrieveTotalRowCount && (arguments.TotalRowCount == -1)) {
                throw new InvalidOperationException(String.Format(CultureInfo.InvariantCulture,
                    AtlasWeb.LinqDataSourceView_PagingNotHandled, _owner.ID));
            } 
            return result;
        } 
 
        private IQueryable ExecuteSelectExpressions(IQueryable source, IDictionary whereValues,
                                                    IOrderedDictionary orderByOrderedValues, 
                                                    IDictionary groupByValues,
                                                    IDictionary orderGroupsByValues,
                                                    IDictionary selectNewValues) {
            IQueryable result = source; 
            string where = Where;
            if (AutoGenerateWhereClause) { 
                if (!String.IsNullOrEmpty(where)) { 
                    throw new InvalidOperationException(String.Format(CultureInfo.InvariantCulture,
                        AtlasWeb.LinqDataSourceView_WhereAlreadySpecified, _owner.ID)); 
                }
                where = GenerateWhereClause(whereValues);
            }
            if (!String.IsNullOrEmpty(where)) { 
                result = _dynamicQueryable.Where(result, where, EscapeParameterKeys(whereValues));
            } 
 
            string orderBy = OrderBy;
            IDictionary orderByValues = null; 
            if (AutoGenerateOrderByClause) {
                if (!String.IsNullOrEmpty(orderBy)) {
                    throw new InvalidOperationException(String.Format(CultureInfo.InvariantCulture,
                        AtlasWeb.LinqDataSourceView_OrderByAlreadySpecified, _owner.ID)); 
                }
                orderBy = GenerateOrderByClause(orderByOrderedValues); 
                orderByValues = new Dictionary(0); 
            }
            else { 
                orderByValues = GetParameterValues(orderByOrderedValues);
            }
            if (!String.IsNullOrEmpty(orderBy)) {
                result = _dynamicQueryable.OrderBy(result, orderBy, EscapeParameterKeys(orderByValues)); 
            }
 
            string groupBy = GroupBy; 
            if (String.IsNullOrEmpty(groupBy)) {
                if (!String.IsNullOrEmpty(OrderGroupsBy)) { 
                    throw new InvalidOperationException(String.Format(CultureInfo.InvariantCulture,
                        AtlasWeb.LinqDataSourceView_OrderGroupsByRequiresGroupBy, _owner.ID));
                }
            } 
            else {
                result = _dynamicQueryable.GroupBy(result, groupBy, "it", EscapeParameterKeys(groupByValues)); 
                string orderGroupsBy = OrderGroupsBy; 
                if (!String.IsNullOrEmpty(orderGroupsBy)) {
                    result = _dynamicQueryable.OrderBy(result, orderGroupsBy, EscapeParameterKeys(orderGroupsByValues)); 
                }
            }

            string selectNew = SelectNew; 
            if (!String.IsNullOrEmpty(selectNew)) {
                result = _dynamicQueryable.Select(result, selectNew, EscapeParameterKeys(selectNewValues)); 
            } 

            return result; 
        }

        private IEnumerable ExecuteSelectQuery(LinqDataSourceSelectEventArgs selectEventArgs, object selectResult,
                                               object table, bool storeOriginalValues) { 
            IList result = null;
            if (selectResult != null) { 
                try { 
                    IQueryable query = AsQueryable(selectResult);
                    query = ExecuteSelectExpressions(query, selectEventArgs.WhereParameters, 
                                                     selectEventArgs.OrderByParameters,
                                                     selectEventArgs.GroupByParameters,
                                                     selectEventArgs.OrderGroupsByParameters,
                                                     selectEventArgs.SelectParameters); 
                    query = ExecuteSelectAutoSortAndPage(query, selectEventArgs.Arguments);
 
                    Type dataObjectType = GetDataObjectType(query.GetType()); 
                    result = ToList(query, dataObjectType);
 
                    if (storeOriginalValues) {
                        ITable dlinqTable = table as ITable;
                        if ((dlinqTable != null) && dataObjectType.Equals(GetDataObjectType(dlinqTable.GetType()))) {
                            StoreOriginalValues(dlinqTable, dataObjectType, result); 
                        }
                    } 
                } 
                catch (Exception e) {
                    result = null; 
                    LinqDataSourceStatusEventArgs selectedEventArgs = new LinqDataSourceStatusEventArgs(e);
                    OnSelected(selectedEventArgs);
                    if (!selectedEventArgs.ExceptionHandled) {
                        throw; 
                    }
                } 
                finally { 
                    if (result != null) {
                        LinqDataSourceStatusEventArgs selectedEventArgs = new LinqDataSourceStatusEventArgs(result); 
                        OnSelected(selectedEventArgs);
                    }
                }
            } 
            return result;
        } 
 
        protected override int ExecuteUpdate(IDictionary keys, IDictionary values, IDictionary oldValues) {
            ValidateUpdateSupported(keys, values, oldValues); 
            EnsureContextAndTable(false);

            if (_table != null) {
                LinqDataSourceEditData editData = null; 
                LinqDataSourceUpdateEventArgs updateEventArgs = null;
                try { 
                    editData = BuildUpdateDataObjects(_table, keys, values, oldValues); 
                }
                catch (LinqDataSourceValidationException e) { 
                    // allow user to handle conversion or dlinq property validation exceptions.
                    updateEventArgs = new LinqDataSourceUpdateEventArgs(e);
                    OnUpdating(updateEventArgs);
                    if (updateEventArgs.ExceptionHandled) { 
                        return -1;
                    } 
                    throw; 
                }
                updateEventArgs = new LinqDataSourceUpdateEventArgs(editData.OriginalDataObject, editData.NewDataObject); 
                OnUpdating(updateEventArgs);
                if (updateEventArgs.Cancel) {
                    return -1;
                } 

                LinqDataSourceStatusEventArgs updatedEventArgs = null; 
                try { 
                    UpdateDataObject(_dataContext, _table, updateEventArgs.OriginalObject, updateEventArgs.NewObject);
                } 
                catch (Exception e) {
                    ResetDataObject(_table, updateEventArgs.OriginalObject);
                    // allow user to handle dlinq exceptions including OnValidate validation.
                    updatedEventArgs = new LinqDataSourceStatusEventArgs(e); 
                    OnUpdated(updatedEventArgs);
                    if (updatedEventArgs.ExceptionHandled) { 
                        return -1; 
                    }
                    throw; 
                }
                updatedEventArgs = new LinqDataSourceStatusEventArgs(updateEventArgs.NewObject);
                OnUpdated(updatedEventArgs);
            } 
            // estimated number of rows updated.
            return 1; 
        } 

        private string GenerateOrderByClause(IOrderedDictionary orderByParameters) { 
            if ((orderByParameters != null) && (orderByParameters.Count > 0)) {
                StringBuilder orderBy = new StringBuilder();
                foreach (DictionaryEntry parameter in orderByParameters) {
                    string value = (string)parameter.Value; 
                    // exclude null and empty values.
                    if (!String.IsNullOrEmpty(value)) { 
                        string name = (string)parameter.Key; 
                        ValidateOrderByParameter(name, value);
                        if (orderBy.Length > 0) { 
                            orderBy.Append(", ");
                        }
                        orderBy.Append(value);
                    } 
                }
                return orderBy.ToString(); 
            } 
            return String.Empty;
        } 

        private string GenerateWhereClause(IDictionary whereParameters) {
            if ((whereParameters != null) && (whereParameters.Count > 0)) {
                StringBuilder where = new StringBuilder(); 
                foreach (KeyValuePair parameter in whereParameters) {
                    string key = parameter.Key; 
                    string value = (parameter.Value == null) ? null : parameter.Value.ToString(); 
                    // exclude null and empty values.
                    if (!(String.IsNullOrEmpty(key) || String.IsNullOrEmpty(value))) { 
                        if (where.Length > 0) {
                            where.Append(" AND ");
                        }
                        where.Append(key); 
                        // the parser will get the parameter value in the substitution values dictionary.
                        where.Append(" == @"); 
                        where.Append(key); 
                    }
                } 
                return where.ToString();
            }
            return String.Empty;
        } 

        protected virtual Type GetDataObjectType(Type tableType) { 
            if (tableType.IsGenericType) { 
                Type[] genericTypes = tableType.GetGenericArguments();
                if (genericTypes.Length == 1) { 
                    return genericTypes[0];
                }
            }
            return typeof(object); 
        }
 
        private IOrderedDictionary GetOrderedParameterValues(ParameterCollection parameters) { 
            IOrderedDictionary orderedValues = new OrderedDictionary(StringComparer.OrdinalIgnoreCase);
            IDictionary parameterValues = parameters.GetValues(_context, _owner); 
            foreach (DictionaryEntry entry in parameterValues) {
                orderedValues[entry.Key] = entry.Value;
            }
            return orderedValues; 
        }
 
        private IDictionary GetOriginalValues(IDictionary keys) { 
            // Table data is stored in a hashtable with column names for keys and an ArrayList of row data for values.
            // i.e, Hashtable { ID = ArrayList { 0, 1, 2 }, Name = ArrayList { "A", "B", "C" } } 
            if (_originalValues != null) {
                // matches list keeps track of row indexes which match.
                List matches = new List();
                foreach (DictionaryEntry entry in keys) { 
                    string propertyName = (String)entry.Key;
                    if (_originalValues.ContainsKey(propertyName)) { 
                        object propertyValue = entry.Value; 
                        // get the row values for the current column.
                        ArrayList values = (ArrayList)_originalValues[propertyName]; 
                        for (int i = 0; i < values.Count; i++) {
                            if (matches.Count <= i) { // first column
                                matches.Add(OriginalValueMatches(values[i], propertyValue));
                            } 
                            else if (matches[i] == true) { // subsequent columns
                                matches[i] = OriginalValueMatches(values[i], propertyValue); 
                            } 
                        }
                    } 
                }

                int rowIndex = matches.IndexOf(true);
                // no rows match or too many rows match. 
                if ((rowIndex < 0) || (matches.IndexOf(true, rowIndex + 1) >= 0)) {
                    throw new InvalidOperationException(AtlasWeb.LinqDataSourceView_OriginalValuesNotFound); 
                } 
                // get original values for the matching row.
                Dictionary rowValues = new Dictionary(_originalValues.Count, 
                    StringComparer.OrdinalIgnoreCase);
                foreach (DictionaryEntry entry in _originalValues) {
                    ArrayList value = (ArrayList)entry.Value;
                    rowValues.Add((string)entry.Key, value[rowIndex]); 
                }
                return rowValues; 
            } 

            return null; 
        }

        private IDictionary GetParameterValues(IOrderedDictionary parameterValues) {
            // NOTE: Dynamic parser requires Dictionary as the last object 
            // in the params array for named parameters.
            Dictionary values = new Dictionary(parameterValues.Count, 
                StringComparer.OrdinalIgnoreCase); 
            foreach (DictionaryEntry entry in parameterValues) {
                values[(string)entry.Key] = entry.Value; 
            }
            return values;
        }
 
        private IDictionary GetParameterValues(ParameterCollection parameters) {
            return GetParameterValues(parameters.GetValues(_context, _owner)); 
        } 

        protected virtual MemberInfo GetTableMemberInfo(Type contextType) { 
            string tableName = TableName;
            if (String.IsNullOrEmpty(tableName)) {
                throw new InvalidOperationException(String.Format(CultureInfo.InvariantCulture,
                    AtlasWeb.LinqDataSourceView_TableNameNotSpecified, _owner.ID)); 
            }
 
            MemberInfo[] members = contextType.FindMembers(MemberTypes.Field | MemberTypes.Property, 
                                                           BindingFlags.Public | BindingFlags.Instance |
                                                           BindingFlags.Static, /*filter*/null, /*filterCriteria*/null); 

            for (int i = 0; i < members.Length; i++) {
                if (String.Equals(members[i].Name, tableName, StringComparison.OrdinalIgnoreCase)) {
                    return members[i]; 
                }
            } 
            return null; 
        }
 
        private ReadOnlyCollection GetTableMetaDataMembers(ITable table, Type dataObjectType) {
            DataContext context = ((ITable)table).Context;
            MetaModel contextMetaData = context.Mapping;
            MetaTable tableMetaData = contextMetaData.GetTable(dataObjectType); 
            MetaType rowMetaData = tableMetaData.RowType;
            return rowMetaData.DataMembers; 
        } 

        public int Insert(IDictionary values) { 
            return ExecuteInsert(values);
        }

        [SuppressMessage("Microsoft.Naming", "CA1720:AvoidTypeNamesInParameters", MessageId = "2#", 
            Justification = "Names are consistent with those used in the ObjectDataSource classes")]
        protected virtual void InsertDataObject(object dataContext, object table, object newDataObject) { 
            _linqToSql.Add((ITable)table, newDataObject); 
            _linqToSql.SubmitChanges((DataContext)dataContext);
        } 

        protected virtual void LoadViewState(object savedState) {
            if (savedState != null) {
                object[] myState = (object[])savedState; 

                if (myState[0] != null) { 
                    ((IStateManager)WhereParameters).LoadViewState(myState[0]); 
                }
                if (myState[1] != null) { 
                    ((IStateManager)OrderByParameters).LoadViewState(myState[1]);
                }
                if (myState[2] != null) {
                    ((IStateManager)GroupByParameters).LoadViewState(myState[2]); 
                }
                if (myState[3] != null) { 
                    ((IStateManager)OrderGroupsByParameters).LoadViewState(myState[3]); 
                }
                if (myState[4] != null) { 
                    ((IStateManager)SelectNewParameters).LoadViewState(myState[4]);
                }
                if (myState[5] != null) {
                    _originalValues = new Hashtable((Hashtable)myState[5], StringComparer.OrdinalIgnoreCase); 
                }
            } 
        } 

        private static bool MemberIsStatic(MemberInfo member) { 
            FieldInfo field = member as FieldInfo;
            if (field != null) {
                return field.IsStatic;
            } 
            PropertyInfo property = member as PropertyInfo;
            if (property != null) { 
                MethodInfo propertyGetter = property.GetGetMethod(); 
                return ((propertyGetter != null) && propertyGetter.IsStatic);
            } 
            return false;
        }

        private void MergeDictionaries(object dataObjectType, ParameterCollection referenceValues, IDictionary source, 
                                       IDictionary destination) {
            MergeDictionaries(dataObjectType, referenceValues, source, destination, null); 
        } 

        private static void MergeDictionaries(object dataObjectType, ParameterCollection reference, IDictionary source, 
                                              IDictionary destination, IDictionary destinationCopy) {
            if (source != null) {
                Dictionary convertExceptions = null;
                foreach (DictionaryEntry de in source) { 
                    object value = de.Value;
                    // search for a parameter that corresponds to this dictionary entry. 
                    Parameter referenceParameter = null; 
                    string parameterName = (string)de.Key;
                    foreach (Parameter p in reference) { 
                        if (String.Equals(p.Name, parameterName, StringComparison.OrdinalIgnoreCase)) {
                            referenceParameter = p;
                            break;
                        } 
                    }
                    // use the parameter for type conversion, default value and/or converting empty string to null. 
                    if (referenceParameter != null) { 
                        try {
                            value = Parameter.GetValue(value, referenceParameter.DefaultValue, referenceParameter.Type, 
                                referenceParameter.ConvertEmptyStringToNull, true);
                        }
                        catch (Exception e) {
                            // catch conversion exceptions so they can be handled. Note that conversion throws various 
                            // types of exceptions like InvalidCastException, FormatException, OverflowException, etc.
                            if (convertExceptions == null) { 
                                convertExceptions = new Dictionary(StringComparer.OrdinalIgnoreCase); 
                            }
                            convertExceptions[referenceParameter.Name] = e; 
                        }
                    }
                    // save the value to the merged dictionaries.
                    destination[parameterName] = value; 
                    if (destinationCopy != null) {
                        destinationCopy[parameterName] = value; 
                    } 
                }
 
                // package up conversion exceptions into single exception.
                if (convertExceptions != null) {
                    throw new LinqDataSourceValidationException(String.Format(CultureInfo.InvariantCulture,
                        AtlasWeb.LinqDataSourceView_ValidationFailed, dataObjectType), convertExceptions); 
                }
            } 
        } 

        [SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", MessageId = "0#")] 
        protected virtual void OnContextCreated(LinqDataSourceStatusEventArgs e) {
            EventHandler handler =
                (EventHandler)Events[EventContextCreated];
            if (handler != null) { 
                handler(this, e);
            } 
        } 

        [SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", MessageId = "0#")] 
        protected virtual void OnContextCreating(LinqDataSourceContextEventArgs e) {
            EventHandler handler =
                (EventHandler)Events[EventContextCreating];
            if (handler != null) { 
                handler(this, e);
            } 
        } 

        [SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", MessageId = "0#")] 
        protected virtual void OnContextDisposing(LinqDataSourceDisposeEventArgs e) {
            EventHandler handler =
                (EventHandler)Events[EventContextDisposing];
            if (handler != null) { 
                handler(this, e);
            } 
        } 

        [SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", MessageId = "0#")] 
        protected virtual void OnDeleted(LinqDataSourceStatusEventArgs e) {
            EventHandler handler =
                (EventHandler)Events[EventDeleted];
            if (handler != null) { 
                handler(this, e);
            } 
        } 

        [SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", MessageId = "0#")] 
        protected virtual void OnDeleting(LinqDataSourceDeleteEventArgs e) {
            EventHandler handler =
                (EventHandler)Events[EventDeleting];
            if (handler != null) { 
                handler(this, e);
            } 
        } 

        [SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", MessageId = "0#")] 
        protected virtual void OnInserted(LinqDataSourceStatusEventArgs e) {
            EventHandler handler =
                (EventHandler)Events[EventInserted];
            if (handler != null) { 
                handler(this, e);
            } 
        } 

        [SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", MessageId = "0#")] 
        protected virtual void OnInserting(LinqDataSourceInsertEventArgs e) {
            EventHandler handler =
                (EventHandler)Events[EventInserting];
            if (handler != null) { 
                handler(this, e);
            } 
        } 

        [SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", MessageId = "0#")] 
        protected virtual void OnSelected(LinqDataSourceStatusEventArgs e) {
            EventHandler handler =
                (EventHandler)Events[EventSelected];
            if (handler != null) { 
                handler(this, e);
            } 
        } 

        [SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", MessageId = "0#")] 
        protected virtual void OnSelecting(LinqDataSourceSelectEventArgs e) {
            EventHandler handler =
                (EventHandler)Events[EventSelecting];
            if (handler != null) { 
                handler(this, e);
            } 
        } 

        [SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", MessageId = "0#")] 
        protected virtual void OnUpdated(LinqDataSourceStatusEventArgs e) {
            EventHandler handler =
                (EventHandler)Events[EventUpdated];
            if (handler != null) { 
                handler(this, e);
            } 
        } 

        [SuppressMessage("Microsoft.Security", "CA2109:ReviewVisibleEventHandlers", MessageId = "0#")] 
        protected virtual void OnUpdating(LinqDataSourceUpdateEventArgs e) {
            EventHandler handler =
                (EventHandler)Events[EventUpdating];
            if (handler != null) { 
                handler(this, e);
            } 
        } 

        private bool OriginalValueMatches(object originalValue, object value) { 
            // NOTE: Comparing IEnumerable contents instead of instances to ensure that
            // timestamp columns (of type byte[]) can be matched appropriately.
            IEnumerable originalValueEnumerable = originalValue as IEnumerable;
            IEnumerable valueEnumerable = value as IEnumerable; 
            if ((originalValueEnumerable != null) && (valueEnumerable != null)) {
                return LinqDataSourceHelper.EnumerableContentEquals(originalValueEnumerable, valueEnumerable); 
            } 
            return originalValue.Equals(value);
        } 

        internal void ReleaseContext() {
            if (_dataContext != null) {
                LinqDataSourceDisposeEventArgs disposingEventArgs = new LinqDataSourceDisposeEventArgs(_dataContext); 
                OnContextDisposing(disposingEventArgs);
                if (!disposingEventArgs.Cancel) { 
                    IDisposable disposableObject = _dataContext as IDisposable; 
                    if (disposableObject != null) {
                        disposableObject.Dispose(); 
                    }
                }
            }
        } 

        [SuppressMessage("Microsoft.Naming", "CA1720:AvoidTypeNamesInParameters", 
            Justification = "Names are consistent with those used in the ObjectDataSource classes")] 
        protected virtual void ResetDataObject(object table, object dataObject) {
            object originalDataObject = _linqToSql.GetOriginalEntityState((ITable)table, dataObject); 
            SetDataObjectProperties(dataObject, originalDataObject);
        }

        private object SaveParametersViewState(ParameterCollection parameters) { 
            if ((parameters != null) && (parameters.Count > 0)) {
                return ((IStateManager)parameters).SaveViewState(); 
            } 
            return null;
        } 

        protected virtual object SaveViewState() {
            object[] myState = new object[6];
            // Saving ViewState for Selection parameters which are tracked for changes.  Parameter 
            // values are updated in LoadComplete and changes will trigger a DataSourceViewChanged
            // event to indicate that data binding is required. 
            myState[0] = SaveParametersViewState(_whereParameters); 
            myState[1] = SaveParametersViewState(_orderByParameters);
            myState[2] = SaveParametersViewState(_groupByParameters); 
            myState[3] = SaveParametersViewState(_orderGroupsByParameters);
            myState[4] = SaveParametersViewState(_selectNewParameters);
            if ((_originalValues != null) && (_originalValues.Count > 0)) {
                myState[5] = (object)_originalValues; 
            }
            return myState; 
        } 

        public IEnumerable Select(DataSourceSelectArguments arguments) { 
            return ExecuteSelect(arguments);
        }

        private void SelectParametersChangedEventHandler(object o, EventArgs e) { 
            OnDataSourceViewChanged(EventArgs.Empty);
        } 
 
        private Dictionary SetDataObjectProperties(object oldDataObject, object newDataObject) {
            Dictionary validateExceptions = null; 

            PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(oldDataObject);
            foreach (PropertyDescriptor property in properties) {
                if (property.PropertyType.IsSerializable && !property.IsReadOnly) { 
                    object newValue = property.GetValue(newDataObject);
                    try { 
                        property.SetValue(oldDataObject, newValue); 
                    }
                    catch (Exception e) { 
                        if (validateExceptions == null) {
                            validateExceptions = new Dictionary(StringComparer.OrdinalIgnoreCase);
                        }
                        validateExceptions[property.Name] = e; 
                    }
                } 
            } 

            return validateExceptions; 
        }

        [SuppressMessage("Microsoft.Security", "CA2116:AptcaMethodsShouldOnlyCallAptcaMethods",
                         Justification = "System.Data.Linq assembly will be changing to support partial trust.")] 
        private void StoreOriginalValues(ITable table, Type dataObjectType, IList result) {
            // Storing columns required for Update and Delete: primary keys, timestamps and those marked for UpdateCheck. 
            // Table data is stored in a hashtable with column names for keys and an ArrayList of row data for values. 
            // i.e, Hashtable { ID = ArrayList { 0, 1, 2 }, Name = ArrayList { "A", "B", "C" } }
            ReadOnlyCollection columns = GetTableMetaDataMembers(table, dataObjectType); 
            if (columns != null) {
                int numRows = result.Count;
                int maxColumns = columns.Count;
                List columnsToStore = new List(maxColumns); 
                _originalValues = new Hashtable(maxColumns, StringComparer.OrdinalIgnoreCase);
                foreach (MetaDataMember column in columns) { 
                    if (column.Type.IsSerializable && 
                        (column.IsPrimaryKey || column.IsVersion || (column.UpdateCheck != UpdateCheck.Never))) {
                        columnsToStore.Add(column); 
                        _originalValues[column.Member.Name] = new ArrayList(numRows);
                    }
                }
                foreach (object currentRow in result) { 
                    foreach (MetaDataMember column in columnsToStore) {
                        MetaAccessor columnAccessor = column.MemberAccessor; 
                        object value = columnAccessor.GetBoxedValue(currentRow); 
                        ((ArrayList)_originalValues[column.Member.Name]).Add(value);
                    } 
                }
            }
        }
 
        private IList ToList(IQueryable query, Type dataObjectType) {
            MethodInfo toListMethod = typeof(Enumerable).GetMethod("ToList").MakeGenericMethod(dataObjectType); 
            return (IList)toListMethod.Invoke(null, new object[] { query }); 
        }
 
        private void TrackParametersViewState(ParameterCollection parameters) {
            if ((parameters != null) && (parameters.Count > 0)) {
                ((IStateManager)parameters).TrackViewState();
            } 
        }
 
        protected virtual void TrackViewState() { 
            _tracking = true;
            TrackParametersViewState(_whereParameters); 
            TrackParametersViewState(_orderByParameters);
            TrackParametersViewState(_groupByParameters);
            TrackParametersViewState(_orderGroupsByParameters);
            TrackParametersViewState(_selectNewParameters); 
        }
 
        public int Update(IDictionary keys, IDictionary values, IDictionary oldValues) { 
            return ExecuteUpdate(keys, values, oldValues);
        } 

        [SuppressMessage("Microsoft.Naming", "CA1720:AvoidTypeNamesInParameters",
            Justification = "Names are consistent with those used in the ObjectDataSource classes")]
        protected virtual void UpdateDataObject(object dataContext, object table, 
                                                object oldDataObject, object newDataObject) {
            _linqToSql.Attach((ITable)table, oldDataObject); 
            Dictionary validateExceptions = SetDataObjectProperties(oldDataObject, newDataObject); 

            // package up dlinq validation exceptions into single exception. 
            if (validateExceptions != null) {
                throw new LinqDataSourceValidationException(String.Format(CultureInfo.InvariantCulture,
                    AtlasWeb.LinqDataSourceView_ValidationFailed, oldDataObject.GetType()), validateExceptions);
            } 

            _linqToSql.SubmitChanges((DataContext)dataContext); 
        } 

        protected virtual void ValidateContextType(Type contextType, bool selecting) { 
            if (!selecting) {
                if (!typeof(DataContext).IsAssignableFrom(contextType)) {
                    throw new InvalidOperationException(String.Format(CultureInfo.InvariantCulture,
                        AtlasWeb.LinqDataSourceView_InvalidContextType, _owner.ID)); 
                }
            } 
        } 

        protected virtual void ValidateDeleteSupported(IDictionary keys, IDictionary oldValues) { 
            if (!CanDelete) {
                throw new NotSupportedException(String.Format(CultureInfo.InvariantCulture,
                AtlasWeb.LinqDataSourceView_DeleteNotSupported, _owner.ID));
            } 
            ValidateEditSupported();
        } 
 
        private void ValidateEditSupported() {
            if (!String.IsNullOrEmpty(GroupBy)) { 
                throw new InvalidOperationException(String.Format(CultureInfo.InvariantCulture,
                    AtlasWeb.LinqDataSourceView_GroupByNotSupportedOnEdit, _owner.ID));
            }
            if (!String.IsNullOrEmpty(SelectNew)) { 
                throw new InvalidOperationException(String.Format(CultureInfo.InvariantCulture,
                    AtlasWeb.LinqDataSourceView_SelectNewNotSupportedOnEdit, _owner.ID)); 
            } 
        }
 
        protected virtual void ValidateInsertSupported(IDictionary values) {
            if (!CanInsert) {
                throw new NotSupportedException(String.Format(CultureInfo.InvariantCulture,
                AtlasWeb.LinqDataSourceView_InsertNotSupported, _owner.ID)); 
            }
            ValidateEditSupported(); 
            if ((values == null) || (values.Count == 0)) { 
                throw new InvalidOperationException(String.Format(CultureInfo.InvariantCulture,
                    AtlasWeb.LinqDataSourceView_InsertRequiresValues, _owner.ID)); 
            }
        }

        protected virtual void ValidateOrderByParameter(string name, string value) { 
            if (!_autoGenerateOrderByRegex.IsMatch(value)) {
                throw new InvalidOperationException(String.Format(CultureInfo.InvariantCulture, 
                    AtlasWeb.LinqDataSourceView_InvalidOrderByFieldName, value, name)); 
            }
        } 

        protected virtual void ValidateParameterName(string name) {
            if (!_identifierRegex.IsMatch(name)) {
                throw new InvalidOperationException(String.Format(CultureInfo.InvariantCulture, 
                    AtlasWeb.LinqDataSourceView_InvalidParameterName, name, _owner.ID));
            } 
        } 

        protected virtual void ValidateTableType(Type tableType, bool selecting) { 
            if (!selecting) {
                if (!(tableType.IsGenericType &&
                    tableType.GetGenericTypeDefinition().Equals(typeof(Table<>)))) {
                    throw new InvalidOperationException(String.Format(CultureInfo.InvariantCulture, 
                        AtlasWeb.LinqDataSourceView_InvalidTablePropertyType, _owner.ID));
                } 
            } 
        }
 
        protected virtual void ValidateUpdateSupported(IDictionary keys, IDictionary values, IDictionary oldValues) {
            if (!CanUpdate) {
                throw new NotSupportedException(String.Format(CultureInfo.InvariantCulture,
                AtlasWeb.LinqDataSourceView_UpdateNotSupported, _owner.ID)); 
            }
            ValidateEditSupported(); 
        } 

        #region IStateManager implementation 
        bool IStateManager.IsTrackingViewState {
            get {
                return IsTrackingViewState;
            } 
        }
 
        void IStateManager.LoadViewState(object savedState) { 
            LoadViewState(savedState);
        } 

        object IStateManager.SaveViewState() {
            return SaveViewState();
        } 

        void IStateManager.TrackViewState() { 
            TrackViewState(); 
        }
        #endregion 

    }
}
 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.


                        

                        

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