EntityDataSourceView.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / DataWebControls / System / Data / WebControls / EntityDataSourceView.cs / 1599186 / EntityDataSourceView.cs

                            //---------------------------------------------------------------------- 
// 
//      Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// 
// @owner       [....]
// @backupOwner [....] 
//--------------------------------------------------------------------- 
using System.Collections;
using System.Collections.Generic; 
using System.Collections.Specialized;
using System.ComponentModel;
using System.Data;
using System.Data.Common; 
using System.Data.Metadata.Edm;
using System.Data.Objects; 
using System.Diagnostics; 
using System.Globalization;
using System.Linq; 
using System.Reflection;
using System.Text;
using System.Web.DynamicData;
using System.Runtime.CompilerServices; 

namespace System.Web.UI.WebControls 
{ 
    public sealed class EntityDataSourceView : DataSourceView, IStateManager
    { 
        private EntityDataSource _owner;
        private ObjectContext _ctx = null;
        private ReadOnlyMetadataCollection _keyMembers = null;
        private EntityDataSourceWrapperCollection _wrapperCollection = null; 

        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 static readonly object EventException = new object();
        private static readonly object EventQueryCreated = new object(); 

        // values saved in ViewState
        private bool _disableUpdates = false;
        private bool _tracking = false; 

        private Dictionary _originalProperties; 
 
        #region Constructor
        internal EntityDataSourceView(EntityDataSource owner, string viewName) 
            : base(owner, viewName)
        {
            _owner = owner;
        } 
        #endregion Constructor
 
        #region ExecuteSelect 

        private static readonly MethodInfo _executeSelectMethod = typeof(EntityDataSourceView).GetMethod("ExecuteSelectTyped", BindingFlags.NonPublic | BindingFlags.Instance); 
        private static readonly MethodInfo _continueSelectMethod = typeof(EntityDataSourceView).GetMethod("ContinueSelectTyped", BindingFlags.NonPublic | BindingFlags.Instance);
        private static readonly Type[] queryBuilderCreatorArgTypes = { typeof(DataSourceSelectArguments), typeof(string), typeof(ObjectParameter[]),
                                                                             typeof(string), typeof(ObjectParameter[]), typeof(string),
                                                                             typeof(string), typeof(string), typeof(ObjectParameter[]), 
                                                                             typeof(OrderByBuilder), typeof(string) };
 
        [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] 
        protected override IEnumerable ExecuteSelect(DataSourceSelectArguments arguments)
        { 
            _wrapperCollection = null;

            AddSupportedCapabilities(arguments);
            arguments.RaiseUnsupportedCapabilitiesError(this); 

            ConstructContext(); 
 
            var selectArgs = new EntityDataSourceSelectingEventArgs(_owner, arguments);
            OnSelecting(selectArgs); 
            if (selectArgs.Cancel)
            {
                return null;
            } 

            _disableUpdates = _owner.ValidateUpdatableConditions(); 
 
            if (_owner.ValidateWrappable())
            { 
                _wrapperCollection = new EntityDataSourceWrapperCollection(Context, EntitySet, CSpaceFilteredEntityType);
            }

            if (!string.IsNullOrEmpty(_owner.Select)) 
            {
                return ExecuteSelectTyped(arguments, EntityDataSourceRecordQueryBuilder.Create); 
            } 
            else if (!string.IsNullOrEmpty(_owner.CommandText))
            { 
                return ExecuteSelectTyped(arguments, EntityDataSourceObjectQueryBuilder.Create);
            }
            else
            { 
                Type builderType = typeof(EntityDataSourceObjectQueryBuilder<>).MakeGenericType(EntityClrType);
                MethodInfo getCreatorMethod = builderType.GetMethod("GetCreator", BindingFlags.Static | BindingFlags.NonPublic); 
                object createDelegate = getCreatorMethod.Invoke(null, null); 
                try
                { 
                    return (IEnumerable)_executeSelectMethod.MakeGenericMethod(EntityClrType).Invoke(this, new object[] { arguments, createDelegate });
                }
                catch (TargetInvocationException e)
                { 
                    throw e.InnerException;
                } 
            } 
        }
 
        [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
        private IEnumerable ExecuteSelectTyped(DataSourceSelectArguments arguments, EntityDataSourceQueryBuilder.Creator qbConstructor)
        {
            string whereClause; 
            ObjectParameter[] whereParameters;
            GenerateWhereClause(out whereClause, out whereParameters); 
            string entitySetQueryExpression = GenerateEntitySetQueryExpression(); 

            var orderByBuilder = new OrderByBuilder(arguments.SortExpression, _wrapperCollection, 
                _owner.OrderBy, _owner.AutoGenerateOrderByClause, _owner.OrderByParameters,
                CanPage, //There's no need to generate the default OrderBy clause if paging is disabled. Prevents an unnecessary sort at the server.
                _owner);
 
            EntityDataSourceQueryBuilder queryBuilder =
                qbConstructor( 
                        arguments, 
                        _owner.CommandText, _owner.GetCommandParameters(),
                        whereClause, whereParameters, entitySetQueryExpression, 
                        _owner.Select, _owner.GroupBy, _owner.GetSelectParameters(),
                        orderByBuilder,
                        _owner.Include);
 
            // We need to keep two copies, the unsorted and sorted because if the event does not
            // modify the query we'll need to revert back to the unsorted one so we can re-apply the 
            // ESQL sort criteria as part of skip/take. 
            ObjectQuery query = queryBuilder.BuildBasicQuery(Context, arguments.RetrieveTotalRowCount);
            ObjectQuery sortedQuery = queryBuilder.ApplyOrderBy(query); 

            var queryEventArgs = new QueryCreatedEventArgs(sortedQuery);
            OnQueryCreated(queryEventArgs);
 
            var queryReturned = queryEventArgs.Query;
            bool wasQueryModified = (queryReturned != sortedQuery); 
            if (wasQueryModified) 
            {
                // Check that we still have an object query 
                if (queryReturned as ObjectQuery == null)
                {
                    throw new InvalidOperationException(Strings.EntityDataSourceView_QueryCreatedWrongType(queryReturned.GetType().Name, typeof(ObjectQuery).Name));
                } 

                // Check that new type is at least substitutable 
                var elementType = queryReturned.ElementType; 
                if (elementType != typeof(T))
                { 
                    if (!typeof(T).IsAssignableFrom(elementType))
                    {
                        throw new InvalidOperationException(Strings.EntityDataSourceView_QueryCreatedWrongType(queryReturned.GetType().Name, typeof(ObjectQuery).Name));
                    } 

                    // Recreate the query builder for new type and then run it 
                    var newQueryBuilderCreateMethod = typeof(EntityDataSourceObjectQueryBuilder<>).MakeGenericType(queryReturned.ElementType).GetMethod("Create", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic, null, queryBuilderCreatorArgTypes, null); 
                    Debug.Assert(newQueryBuilderCreateMethod != null, "Unable to bind to EntityDataSourceObjectQueryBuilder.Create (static, non-visible) method");
 
                    // If the query results were wrapped before, we need to reset the wrapper to use the new type
                    if (_wrapperCollection != null)
                    {
                        MetadataWorkspace workspace = Context.MetadataWorkspace; 
                        EntityType newOSpaceType = workspace.GetItem(elementType.FullName, DataSpace.OSpace);
                        EntityType newCSpaceType = (EntityType)workspace.GetEdmSpaceType((StructuralType)newOSpaceType); 
 
                        _wrapperCollection = new EntityDataSourceWrapperCollection(Context, EntitySet, newCSpaceType);
 
                        // Don't need to regenerate the where clause and parameters because they must be declaratively specified and if they reference
                        // properties that only exist in the subtype we would have already failed to generate the where clause previously and couldn't get this far

                        // Regeneate the OrderByBuilder so that we can apply the sort expression later based on the new wrapper properties 
                        orderByBuilder = new OrderByBuilder(arguments.SortExpression, _wrapperCollection,
                            _owner.OrderBy, _owner.AutoGenerateOrderByClause, _owner.OrderByParameters, 
                            CanPage, //There's no need to generate the default OrderBy clause if paging is disabled. Prevents an unnecessary sort at the server. 
                            _owner);
                    } 

                    object newQueryBuilder = newQueryBuilderCreateMethod.Invoke(null, new object[] {
                         arguments,
                        _owner.CommandText, _owner.GetCommandParameters(), 
                        whereClause, whereParameters, entitySetQueryExpression,
                        _owner.Select, _owner.GroupBy, _owner.GetSelectParameters(), 
                        orderByBuilder, 
                        _owner.Include });
                    return (IEnumerable)_continueSelectMethod.MakeGenericMethod(elementType).Invoke(this, new object[] { arguments, newQueryBuilder, queryReturned, wasQueryModified }); 
                }

                // Type hasn't changed, we can dispatch as normal
                query = queryReturned as ObjectQuery; 
            }
 
            return ContinueSelectTyped(arguments, queryBuilder, query, wasQueryModified); 
        }
 
        private IEnumerable ContinueSelectTyped(DataSourceSelectArguments arguments, EntityDataSourceQueryBuilder queryBuilder, ObjectQuery queryT, bool wasQueryModified)
        {
            // Reset the MergeOption to AppendOnly
            queryT.MergeOption = MergeOption.AppendOnly; 
            queryT = queryBuilder.CompleteBuild(queryT, Context, arguments.RetrieveTotalRowCount, wasQueryModified);
 
            // SelectedEventArgs.TotalRowCount has three possible states: 
            //  1. The databound control requests it via arguments.RetrieveTotalRowCount
            //     This returns the total number of rows on all pages. 
            //     arguments.TotalRowCount is only set if arguments.RetrieveTotalRowCount is true.
            //  2. Paging is disabled via !CanPage.
            //     This returns the number of rows returned. On one page.
            //  3. Else it returns negative one. 
            int totalRowCount = -1;
 
            if (arguments.RetrieveTotalRowCount) 
            {
                // The Selected event args gets the total number of rows on all pages. 
                totalRowCount = queryBuilder.TotalCount;
                // The databound control requests totalRowCount. We return the total rows on all pages.
                arguments.TotalRowCount = totalRowCount;
            } 

            if (!_disableUpdates) 
            { 
                Debug.Assert(null != EntitySet, "Can't be updatable with a null EntitySet");
                EntityDataSourceUtil. 
                  CheckNonPolymorphicTypeUsage(EntitySet.ElementType,
                                             Context.MetadataWorkspace.GetItemCollection(DataSpace.CSpace),
                                             _owner.EntityTypeFilter);
            } 

            IEnumerable entities = null; 
            try 
            {
                entities = queryBuilder.Execute(queryT); 
            }
            catch (Exception e)
            {
                entities = null; 
                var selectedArgs = new EntityDataSourceSelectedEventArgs(e);
                OnSelected(selectedArgs); 
                OnException(new DynamicValidatorEventArgs(e, DynamicDataSourceOperation.Select)); 
                if (!selectedArgs.ExceptionHandled)
                { 
                    throw;
                }
            }
 
            // OnSelected outside "try" to prevent double-calling OnSelected if the first OnSelected throws
            if (null != entities) 
            { 
                if (!CanPage)
                { 
                    // Paging is disabled, totalRowCount gets the number of rows returned from this query.
                    totalRowCount = ((IList)entities).Count;
                }
                OnSelected(new EntityDataSourceSelectedEventArgs(Context, entities, totalRowCount, arguments)); 
            }
 
            var useWrapperCollection = (_wrapperCollection != null); 
            var checkEntitySet = wasQueryModified && !String.IsNullOrEmpty(_owner.EntitySetName) && (CanDelete || CanUpdate);
 
            if (!useWrapperCollection && !checkEntitySet)
            {
                return entities;
            } 

            foreach (object element in entities) 
            { 
                var elementEntitySet = Context.ObjectStateManager.GetObjectStateEntry(element).EntitySet;
                if (elementEntitySet != EntitySet) 
                {
                    throw new InvalidOperationException(Strings.EntityDataSourceView_EntitySetMismatchWithQueryResults(elementEntitySet, EntitySet));
                }
                if (useWrapperCollection) 
                {
                    _wrapperCollection.AddWrappedEntity(element); 
                } 
            }
 
            return useWrapperCollection ? _wrapperCollection : entities;
        }

        ///  
        /// Restrict the query to the type specified by EntityTypeFilter.
        ///  
        ///  
        private string GenerateEntitySetQueryExpression()
        { 
            if (null == EntitySet)
            {
                return String.Empty;
            } 

            string entitySetIdentifier = EntityDataSourceUtil.CreateEntitySqlSetIdentifier(EntitySet); 
 
            if (String.IsNullOrEmpty(_owner.EntityTypeFilter))
            { 
                return entitySetIdentifier;
            }

            Debug.Assert(EntityOSpaceType != null, "EntitySet is not null, EntityOSpaceType should also be defined."); 

            // oftype ([Northwind].[Products], only [Northwind].[ActiveProducts]) 
            StringBuilder queryExpressionBuilder = new StringBuilder(); 
            queryExpressionBuilder.Append("oftype (");
            queryExpressionBuilder.Append(entitySetIdentifier); 
            queryExpressionBuilder.Append(", only ");
            queryExpressionBuilder.Append(EntityDataSourceUtil.CreateEntitySqlTypeIdentifier(EntityOSpaceType));
            queryExpressionBuilder.Append(")");
 
            return queryExpressionBuilder.ToString();
        } 
 
        #endregion ExecuteSelect
 
        #region ExecuteUpdate

        protected override int ExecuteUpdate(IDictionary keys, IDictionary values, IDictionary oldValues)
        { 
            if (!CanUpdate)
            { 
                throw new InvalidOperationException(Strings.EntityDataSourceView_UpdateDisabledForThisControl); 
            }
 
            ConstructContext();
            EntityDataSourceChangingEventArgs changingArgs;

            Dictionary originalEntityValues = new Dictionary(); 
            EntityDataSourceWrapperCollection wrapperCollection =
                new EntityDataSourceWrapperCollection(Context, EntitySet, CSpaceFilteredEntityType); 
            EntityDataSourceWrapper modifiedEntityWrapper; 
            try
            { 
                object entity = EntityDataSourceUtil.InitializeType(this.EntityClrType);
                Context.AddObject(_owner.FQEntitySetName, entity);
                modifiedEntityWrapper = new EntityDataSourceWrapper(wrapperCollection, entity);
 
                // Get the values in the following order
                // 1. Key values from the page 
                // 2. Values from view state 
                // 3. Values from oldValues
                ConvertProperties(keys, modifiedEntityWrapper.GetProperties(), /* ParameterCollection */null, originalEntityValues); 
                GetValuesFromViewState(originalEntityValues);
                ConvertProperties(oldValues, modifiedEntityWrapper.GetProperties(), /* ParameterCollection */null, originalEntityValues);

                // Populate the entity with values 
                EntityDataSourceUtil.SetAllPropertiesWithVerification(modifiedEntityWrapper, originalEntityValues, /*overwrite*/true);
 
            } 
            catch (EntityDataSourceValidationException e)
            { 
                changingArgs = new EntityDataSourceChangingEventArgs(e);
                OnUpdating(changingArgs);
                OnException(new DynamicValidatorEventArgs(e, DynamicDataSourceOperation.Update));
                if (!changingArgs.ExceptionHandled) 
                {
                    throw; 
                } 
                return -1;
            } 

            //Modify the properties with the new values
            try
            { 
                Context.AcceptAllChanges(); //Puts modifiedEntityWrapper into unchanged state.
                UpdateEntity(originalEntityValues, values, modifiedEntityWrapper, _owner.UpdateParameters); 
            } 
            catch (EntityDataSourceValidationException e)
            { 
                changingArgs = new EntityDataSourceChangingEventArgs(e);
                OnUpdating(changingArgs);
                OnException(new DynamicValidatorEventArgs(e, DynamicDataSourceOperation.Update));
                if (!changingArgs.ExceptionHandled) 
                {
                    throw; 
                } 
                return -1;
            } 
            try
            {
                // Call DetectChanges to ensure the changes to the entity are reflected in the state manager
                Context.DetectChanges(); 
            }
            catch (Exception e) 
            { 
                changingArgs = new EntityDataSourceChangingEventArgs(e);
                OnUpdating(changingArgs); 
                OnException(new DynamicValidatorEventArgs(e, DynamicDataSourceOperation.Update));
                if (!changingArgs.ExceptionHandled)
                {
                    throw; 
                }
                return -1; 
            } 

            try 
            {
                // Call DetectChanges to ensure the changes to the entity are reflected in the state manager
                Context.DetectChanges();
            } 
            catch (Exception e)
            { 
                changingArgs = new EntityDataSourceChangingEventArgs(e); 
                OnUpdating(changingArgs);
                OnException(new DynamicValidatorEventArgs(e, DynamicDataSourceOperation.Update)); 
                if (!changingArgs.ExceptionHandled)
                {
                    throw;
                } 
                return -1;
            } 
 
            changingArgs = new EntityDataSourceChangingEventArgs(Context, modifiedEntityWrapper.WrappedEntity);
            OnUpdating(changingArgs); 
            if (changingArgs.Cancel)
            {
                return -1;
            } 

            try 
            { 
                Context.SaveChanges();
            } 
            catch (Exception e)
            {
                // Catches SaveChanges exceptions.
                EntityDataSourceChangedEventArgs changedArgs = new EntityDataSourceChangedEventArgs(e); 
                OnUpdated(changedArgs);
                OnException(new DynamicValidatorEventArgs(e, DynamicDataSourceOperation.Update)); 
                if (!changedArgs.ExceptionHandled) 
                {
                    throw; 
                }
                return -1;
            }
            OnUpdated(new EntityDataSourceChangedEventArgs(Context, modifiedEntityWrapper.WrappedEntity)); 
            return 1;
 
        } 

        #endregion ExecuteUpdate 

        #region ExecuteDelete
        protected override int ExecuteDelete(IDictionary keys, IDictionary oldValues)
        { 
            if (!CanDelete)
            { 
                throw new InvalidOperationException(Strings.EntityDataSourceView_DeleteDisabledForThiscontrol); 
            }
 
            ConstructContext();

            EntityDataSourceWrapperCollection wrapperCollection = new EntityDataSourceWrapperCollection(Context, EntitySet, CSpaceFilteredEntityType);
            EntityDataSourceWrapper entityWrapper; 
            object entity;
            EntityDataSourceChangingEventArgs changingArgs; 
            try 
            {
                entity = EntityDataSourceUtil.InitializeType(this.EntityClrType); 
                Context.AddObject(_owner.FQEntitySetName, entity); // Add/AcceptAllChanges because wrappers must contain attached entities
                entityWrapper = new EntityDataSourceWrapper(wrapperCollection, entity);

                // Get the values in the following order 
                // 1. Key values from the page
                // 2. Values from view state 
                // 3. Values from oldValues 
                Dictionary entityValues = new Dictionary();
                ConvertProperties(keys, entityWrapper.GetProperties(), _owner.DeleteParameters, entityValues); 
                GetValuesFromViewState(entityValues);
                ConvertProperties(oldValues, entityWrapper.GetProperties(), _owner.DeleteParameters, entityValues);

                // Populate the entity with values 
                EntityDataSourceUtil.SetAllPropertiesWithVerification(entityWrapper, entityValues, /*overwrite*/true);
 
                Context.AcceptAllChanges(); //Force the entity just added into unchanged state. Wrapped entities must be tracked. 
            }
            catch (EntityDataSourceValidationException e) 
            {
                changingArgs = new EntityDataSourceChangingEventArgs(e);
                OnDeleting(changingArgs);
                OnException(new DynamicValidatorEventArgs(e, DynamicDataSourceOperation.Delete)); 
                if (!changingArgs.ExceptionHandled)
                { 
                    throw; 
                }
                return -1; 
            }
            changingArgs = new EntityDataSourceChangingEventArgs(Context, entityWrapper.WrappedEntity);
            OnDeleting(changingArgs); //Outside "try" to prevent from begin called twice.
            if (changingArgs.Cancel) 
            {
                return -1; 
            } 

            try 
            {
                Context.DeleteObject(entityWrapper.WrappedEntity);
                Context.SaveChanges();
            } 
            catch (Exception e)
            { 
                // Catches errors on the context. 
                EntityDataSourceChangedEventArgs changedArgs = new EntityDataSourceChangedEventArgs(e);
                OnDeleted(changedArgs); 
                OnException(new DynamicValidatorEventArgs(e, DynamicDataSourceOperation.Delete));
                if (!changedArgs.ExceptionHandled)
                {
                    throw; 
                }
                return -1; 
            } 
            OnDeleted(new EntityDataSourceChangedEventArgs(Context, entity)); //Outside "try" to prevent being called twice.
            return 1; 
        }
        #endregion ExecuteDelete

        #region ExecuteInsert 

        protected override int ExecuteInsert(IDictionary values) 
        { 
            if (!CanInsert)
            { 
                throw new InvalidOperationException(Strings.EntityDataSourceView_InsertDisabledForThisControl);
            }

            ConstructContext(); 

            EntityDataSourceChangingEventArgs changingArgs; 
            EntityDataSourceWrapperCollection wrapperCollection = new EntityDataSourceWrapperCollection(Context, EntitySet, CSpaceFilteredEntityType); 
            EntityDataSourceWrapper entityWrapper;
            try 
            {
                object entity = EntityDataSourceUtil.InitializeType(this.EntityClrType);
                Context.AddObject(_owner.FQEntitySetName, entity);
                entityWrapper = new EntityDataSourceWrapper(wrapperCollection, entity); 
                CreateEntityForInsert(entityWrapper, values, _owner.InsertParameters);
            } 
            catch (EntityDataSourceValidationException e) 
            {
                changingArgs = new EntityDataSourceChangingEventArgs(e); 
                OnInserting(changingArgs);
                OnException(new DynamicValidatorEventArgs(e, DynamicDataSourceOperation.Insert));
                if (!changingArgs.ExceptionHandled)
                { 
                    throw;
                } 
                return -1; 
            }
 
            changingArgs = new EntityDataSourceChangingEventArgs(Context, entityWrapper.WrappedEntity);
            OnInserting(changingArgs); //Could return an entity to insert.
            if (changingArgs.Cancel)
            { 
                return -1;
            } 
 
            if (!Object.ReferenceEquals(entityWrapper.WrappedEntity, changingArgs.Entity))
            { 
                Context.Detach(entityWrapper.WrappedEntity);
                Context.AddObject(_owner.EntitySetName, changingArgs.Entity);
                entityWrapper = new EntityDataSourceWrapper(wrapperCollection, changingArgs.Entity);
            } 

            try 
            { 
                Context.SaveChanges();
            } 
            catch (Exception e)
            {
                EntityDataSourceChangedEventArgs changedArgs = new EntityDataSourceChangedEventArgs(e);
                OnInserted(changedArgs); 
                OnException(new DynamicValidatorEventArgs(e, DynamicDataSourceOperation.Insert));
                if (!changedArgs.ExceptionHandled) 
                { 
                    throw;
                } 
                return -1;
            }
            OnInserted(new EntityDataSourceChangedEventArgs(Context, entityWrapper.WrappedEntity));
            return 1; 
        }
 
        #endregion ExecuteInsert 

        #region Public Methods 
        public DataTable GetViewSchema()
        {
            EntityDataSourceViewSchema propTable;
            if (_owner.ValidateWrappable()) 
            {
                ConstructContext(); 
                EntityDataSourceWrapperCollection wrappers = new EntityDataSourceWrapperCollection(Context, EntitySet, CSpaceFilteredEntityType); 
                propTable = new EntityDataSourceViewSchema(wrappers);
            } 
            else
            {
                string where = _owner.Where;
                _owner.Where = "0=1"; 
                try
                { 
                    DataSourceSelectArguments args = new DataSourceSelectArguments(); 
                    args.RetrieveTotalRowCount = false;
                    IEnumerable results = ExecuteSelect(args); 
                    ITypedList typedList = results as ITypedList;
                    if (null != typedList)
                    {
                        propTable = new EntityDataSourceViewSchema(typedList); 
                    }
                    else if (_owner.HasIdentity()) 
                    { 
                        // If the results have an identity/primary keys, gather them from restricted type or the element type from the set the control is querying
                        // Make sure to use keys from the ObjectSpace type in case there were name mappings 
                        EntityType entityType = Context.MetadataWorkspace.GetObjectSpaceType(CSpaceFilteredEntityType ?? EntitySet.ElementType) as EntityType;
                        propTable = new EntityDataSourceViewSchema(results, entityType.KeyMembers.Select(x => x.Name).ToArray());
                    }
                    else 
                    {
                        propTable = new EntityDataSourceViewSchema(results); 
                    } 
                }
                finally 
                {
                    _owner.Where = where;
                }
            } 
            return propTable;
        } 
        #endregion Public Methods 

        #region Private Methods 

        #region ExecuteSelect Support

        private void GenerateWhereClause(out string whereClause, out ObjectParameter[] whereParameters) 
        {
            if (!_owner.AutoGenerateWhereClause) 
            { 
                whereClause = _owner.Where;
                whereParameters = _owner.GetWhereParameters(); 
                return;
            }

            //This is the automatically generated Where clause. 
            IOrderedDictionary paramValues = _owner.WhereParameters.GetValues(_owner.HttpContext, _owner);
            // Under some conditions, the paramValues has a null entry. 
            StringBuilder whereClauseBuilder = new StringBuilder(); 
            List whereParameterList = new List();
            bool first = true; 

            int idx = 0;
            foreach (DictionaryEntry de in paramValues)
            { 
                string propertyName = (string)(de.Key);
                if (0 < propertyName.Length && null != de.Value) 
                { 
                    if (!String.IsNullOrEmpty(_owner.EntitySetName) && !EntityDataSourceUtil.PropertyIsOnEntity(propertyName, _wrapperCollection, EntitySet, null))
                    { 
                        throw new InvalidOperationException(Strings.EntityDataSourceView_PropertyDoesNotExistOnEntity(propertyName, EntityClrType.FullName));
                    }

                    if (first) 
                    {
                        first = false; 
                    } 
                    else
                    { 
                        whereClauseBuilder.Append(" AND ");
                    }

                    string namedParameterName = "NamedParameter" + idx.ToString(CultureInfo.InvariantCulture); 

                    whereClauseBuilder.Append(EntityDataSourceUtil.GetEntitySqlValueForColumnName(propertyName, _wrapperCollection)); 
                    whereClauseBuilder.Append("=@"); 
                    whereClauseBuilder.Append(namedParameterName);
 
                    whereParameterList.Add(new ObjectParameter(namedParameterName, de.Value));
                    idx++;
                }
            } 

            whereParameters = whereParameterList.ToArray(); 
            whereClause = whereClauseBuilder.ToString(); 
        }
 
        #endregion ExecuteSelect Support

        #region Entity Creation Support for Update/Insert/Delete
 
        private object ConvertProperty(object origPropertyValue, PropertyDescriptor propertyDescriptor, WebControlParameterProxy referenceParameter)
        { 
            if (null == propertyDescriptor) 
            {
                return null; 
            }

            object propValue = origPropertyValue;
            propValue = Parameter_GetValue(propValue, referenceParameter, true); 
            propValue = EntityDataSourceUtil.ConvertType(propValue, propertyDescriptor.PropertyType, propertyDescriptor.Name);
            return propValue; 
        } 

        private void ConvertWCProperty(IDictionary values, 
            Dictionary convertedValues,
            List visitedProperties,
            PropertyDescriptor pd,
            ParameterCollection referenceParameters, 
            ref Dictionary exceptions)
        { 
            Debug.Assert(pd != null, "PropertyDescriptor is null"); 
            string propertyName = pd.Name;
            WebControlParameterProxy wcParameter = new WebControlParameterProxy(propertyName, referenceParameters, _owner); 
            object propValue = null;
            object value = null;
            if (null != values)
            { 
                value = values[propertyName];
            } 
            try 
            {
                propValue = ConvertProperty(value, pd, wcParameter); 
            }
            catch (Exception e)
            {
                if (null == exceptions) 
                {
                    exceptions = new Dictionary(); 
                } 
                exceptions.Add(propertyName, e);
            } 
            convertedValues[propertyName] = propValue;
            visitedProperties.Add(propertyName);
        }
        private void ConvertProperties(IDictionary values, PropertyDescriptorCollection propertyDescriptors, ParameterCollection referenceParameters, Dictionary convertedValues) 
        {
            List visitedProperties = new List(); 
            Dictionary exceptions = null; 

            // "values" come from the web page. Either via keys or original values. This loops sets them as first priority 
            foreach (string propertyName in values.Keys)
            {
                if (!convertedValues.ContainsKey(propertyName))
                { 
                    PropertyDescriptor pd = propertyDescriptors.Find(propertyName, /*ignoreCase*/ false);
                    if (pd == null) 
                    { 
                        throw new InvalidOperationException(Strings.EntityDataSourceView_UnknownProperty(propertyName));
                    } 
                    ConvertWCProperty(values, convertedValues, visitedProperties,
                        pd, referenceParameters, ref exceptions);
                }
                // else ignore the value because it is already contained in the set of output values 
            }
 
            // If a property hasn't been set by visible columns or DataKeyNames, then we set them here. 
            // "referenceParameters" are Insert, Update or DeleteParameters assigning default values to
            // columns that are not set by the control 
            if (null != referenceParameters)
            {
                IOrderedDictionary referenceValues = referenceParameters.GetValues(_owner.HttpContext, _owner);
                foreach (string propertyName in referenceValues.Keys) 
                {
                    if (!visitedProperties.Contains(propertyName)) 
                    { 
                        PropertyDescriptor pd = propertyDescriptors.Find(propertyName, /*ignoreCase*/ false);
                        if (pd == null) 
                        {
                            throw new InvalidOperationException(Strings.EntityDataSourceView_UnknownProperty(propertyName));
                        }
                        ConvertWCProperty(null, convertedValues, visitedProperties, 
                            pd, referenceParameters, ref exceptions);
                    } 
                } 
            }
 
            if (null != exceptions)
            {
                // The IDynamicValidationException encapsulates all of the data conversion errors.
                // This exposes one of the encapsulated errors in its own message like: 
                //   "Error while setting property 'ProductName': 'The value cannot be null.'."
                string key = exceptions.Keys.First(); 
                throw new EntityDataSourceValidationException( 
                    Strings.EntityDataSourceView_DataConversionError(
                        key, exceptions[key].Message), exceptions); 
            }
        }

        private void CreateEntityForInsert(EntityDataSourceWrapper entityWrapper, IDictionary values, ParameterCollection insertParameters) 
        {
            EntityDataSourceUtil.ValidateWebControlParameterNames(entityWrapper, insertParameters, _owner); 
 
            // Throws EntityDataSourceValidationException if data conversion fails
            Dictionary entityValues = new Dictionary(); 
            ConvertProperties(values, entityWrapper.GetProperties(), insertParameters, entityValues);

            EntityDataSourceUtil.SetAllPropertiesWithVerification(entityWrapper, entityValues, /*overwrite*/true);
        } 

        private void UpdateEntity(Dictionary originalEntityValues, IDictionary values, 
                                  EntityDataSourceWrapper entityWrapper, ParameterCollection updateParameters) 
        {
            EntityDataSourceUtil.ValidateWebControlParameterNames(entityWrapper, updateParameters, _owner); 
            Dictionary currentEntityValues = new Dictionary();
            ConvertProperties(values, entityWrapper.GetProperties(), updateParameters, currentEntityValues);
            Dictionary allModifiedProperties = new Dictionary();
 
            // Compare the propertyValues from the original values from the page to those in the new "values" properties.
            // Note that the comparison is between the values that came back from the databound control, BUT 
            // The values on the entity in the entityWrapper came from ViewState. We can't compare the values from the page 
            // To those stored in ViewState in case they didn't roundtrip well. Hence this next loop.
            foreach (string propertyName in currentEntityValues.Keys) 
            {
                object originalValue = null;
                originalEntityValues.TryGetValue(propertyName, out originalValue);
                object newValue = currentEntityValues[propertyName]; 

                if (!OriginalValueMatches(originalValue, newValue)) 
                { 
                    allModifiedProperties[propertyName] = newValue;
                } 
            }

            EntityDataSourceUtil.SetAllPropertiesWithVerification(entityWrapper, allModifiedProperties, /*overwrite*/false);
        } 

        #endregion Entity Creation Support 
 
        #region ViewState Storage
 
        internal void StoreOriginalPropertiesIntoViewState()
        {
            if (null == _wrapperCollection ||
                0 == _wrapperCollection.Count || 
                !_owner.StoreOriginalValuesInViewState ||
                (!CanDelete && !CanUpdate)) //Only store entities into viewstate if Delete or Update is enabled. 
            { 
                return;
            } 

            _originalProperties = new Dictionary();

            PropertyDescriptorCollection collection = _wrapperCollection.GetItemProperties(null); 

            // Retrieve the named properties from each entity and place them into the viewstate collection. 
            foreach (EntityDataSourceWrapper wrapper in _wrapperCollection) 
            {
                foreach (PropertyDescriptor propertyDescriptor in collection) 
                {
                    EntityDataSourceWrapperPropertyDescriptor wrapperPropertyDescriptor = (EntityDataSourceWrapperPropertyDescriptor)propertyDescriptor;

                    if (wrapperPropertyDescriptor.Column.IsInteresting && wrapperPropertyDescriptor.Column.IsPrimitive) 
                    {
                        object property = wrapperPropertyDescriptor.GetValue(wrapper); 
                        string propertyName = wrapperPropertyDescriptor.DisplayName; 

                        if (!_originalProperties.ContainsKey(propertyName)) 
                        {
                            _originalProperties[propertyName] = new ArrayList();
                        }
 
                        (_originalProperties[propertyName]).Add(property);
                    } 
                } 
            }
        } 

        private void GetValuesFromViewState(Dictionary entityValues)
        {
            int idx = FindIdxOfPropertiesStoredInViewState(entityValues); 

            if (0 <= idx) // "-1" indicates that the value was not found in ViewState 
            { 
                foreach (string propertyName in _originalProperties.Keys)
                { 
                    object property = (_originalProperties[propertyName])[idx];
                    entityValues[propertyName] = property;
                }
            } 
        }
 
        ///  
        /// Returns the index of the entity in ViewState that has key values that match the values from the page.
        /// If a match is not found, it returns -1. 
        /// 
        /// 
        /// 
        private int FindIdxOfPropertiesStoredInViewState(IDictionary mergedKeysAndOldValues) 
        {
            if (null == _originalProperties || 0 == _originalProperties.Count) 
            { 
                return -1;
            } 

            Dictionary localMergedKeysAndOldValues = (Dictionary)mergedKeysAndOldValues;

            // This get the number of entities from the first property's values. 
            // The ArrayList that holds the values contains the count of the number of entities.
            int numEntities = (_originalProperties.First().Value).Count; 
            for (int idx = 0; idx < numEntities; idx++) 
            {
                bool match = true; 
                foreach (EdmMember edmMember in KeyMembers)
                {
                    string propertyName = edmMember.Name;
                    // The page must return the key values. 
                    if (!localMergedKeysAndOldValues.ContainsKey(propertyName))
                    { 
                        match = false; 
                        break;
                    } 

                    object origValue = (_originalProperties[propertyName])[idx];
                    object pageValue = localMergedKeysAndOldValues[propertyName];
                    if (!OriginalValueMatches(origValue, pageValue)) 
                    {
                        match = false; 
                        break; 
                    }
                } 
                if (match)
                {
                    return idx;
                } 
            }
            return -1; 
        } 

        private bool OriginalValueMatches(object originalValue, object value) 
        {
            if (null == originalValue)
            {
                if (null == value) 
                {
                    return true; 
                } 
                return false;
            } 

            // 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 EnumerableContentEquals(originalValueEnumerable, valueEnumerable);
            } 

            return originalValue.Equals(value);
        }
 
        #endregion ViewState Storage
 
        #region Context and Query construction 

        private void ConstructContext() 
        {
            this.DisposeContext();

            Type contextType = null; 
            EntityDataSourceContextCreatingEventArgs creatingArgs = new EntityDataSourceContextCreatingEventArgs();
            OnContextCreating(creatingArgs); 
            if (null != creatingArgs.Context) //Context was created in event code 
            {
                _ctx = creatingArgs.Context; 
                contextType = _ctx.GetType();
            }
            else if (null != _owner.ContextType || !String.IsNullOrEmpty(_owner.ContextTypeName))
            { 
                //Construct the context.
                if (null != _owner.ContextType) 
                { 
                    contextType = _owner.ContextType;
                } 
                else
                {
                    contextType = System.Web.Compilation.BuildManager.GetType(_owner.ContextTypeName, /*throw on error*/ true);
                } 

                ConstructorInfo ctxInfo = contextType.GetConstructor( 
                    BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.CreateInstance, 
                    null, System.Type.EmptyTypes, null);
 
                if (null == ctxInfo)
                {
                    throw new InvalidOperationException(Strings.EntityDataSourceView_NoParameterlessConstructorForTheContext);
                } 

                _ctx = (ObjectContext)ctxInfo.Invoke(new object[0]); 
            } 
            else // Non-strongly-typed context built from ConnectionString and DefaultContainerName
            { 
                if (!String.IsNullOrEmpty(_owner.DefaultContainerName) &&
                    !String.IsNullOrEmpty(_owner.ConnectionString))
                {
                    _ctx = new ObjectContext(_owner.ConnectionString); 

                    if (System.Web.Hosting.HostingEnvironment.IsHosted) 
                    { 
                        // Since we don't have the type from the strongly-typed context,
                        // load from all of the referenced assemblies, including code from App_Code and the top-level directory: 
                        // http://msdn2.microsoft.com/en-us/library/system.web.compilation.buildmanager.getreferencedassemblies.aspx
                        ICollection codeAssemblies = System.Web.Compilation.BuildManager.GetReferencedAssemblies();
                        foreach (Assembly assembly in codeAssemblies)
                        { 
                            _ctx.MetadataWorkspace.LoadFromAssembly(assembly);
                        } 
                    } 
                }
                else if (!String.IsNullOrEmpty(_owner.DefaultContainerName) && 
                          null != _owner.Connection)
                {
                    _ctx = new ObjectContext(_owner.Connection);
                } 
                else
                { 
                    throw new InvalidOperationException(Strings.EntityDataSourceView_ObjectContextMustBeSpecified); 
                }
                // Must set the DefaultContainerName for both of the above conditions. 
                _ctx.DefaultContainerName = _owner.DefaultContainerName;
                contextType = typeof(ObjectContext);

            } 

            _ctx.MetadataWorkspace.LoadFromAssembly(System.Reflection.Assembly.GetCallingAssembly()); 
            _ctx.MetadataWorkspace.LoadFromAssembly(contextType.Assembly); 

 
            // Error Checking on the Context
            ValidateContainerName();

            OnContextCreated(new EntityDataSourceContextCreatedEventArgs(Context)); 
        }
 
        // QueryCreated Event 
        private void OnQueryCreated(QueryCreatedEventArgs e)
        { 
            var handler = (EventHandler)Events[EventQueryCreated];
            if (null != handler)
            {
                handler(this, e); 
            }
        } 
 
        [CLSCompliant(false)]
        public event EventHandler QueryCreated 
        {
            add { Events.AddHandler(EventQueryCreated, value); }
            remove { Events.RemoveHandler(EventQueryCreated, value); }
        } 

        internal void DisposeContext() 
        { 
            if (null != _ctx)
            { 
                EntityDataSourceContextDisposingEventArgs disposeArgs = new EntityDataSourceContextDisposingEventArgs(_ctx);
                OnContextDisposing(disposeArgs);
                if (!disposeArgs.Cancel)
                { 
                    _ctx.Dispose();
                    _ctx = null; 
                } 
            }
        } 

        #endregion Context and Query construction
        #endregion Private Methods
 
        #region Public Overrides
        public override bool CanInsert 
        { 
            get { return _owner.EnableInsert && !_disableUpdates; }
        } 
        public override bool CanUpdate
        {
            get { return _owner.EnableUpdate && !_disableUpdates; }
        } 
        public override bool CanDelete
        { 
            get { return _owner.EnableDelete && !_disableUpdates; } 
        }
        public override bool CanSort 
        {
            get { return _owner.AutoSort; }
        }
        public override bool CanPage 
        {
            get { return _owner.AutoPage; } 
        } 
        public override bool CanRetrieveTotalRowCount
        { 
            get { return _owner.AutoPage; }
        }
        #endregion Public Overrides
 
        #region Events
 
        //Oryx exception event 
        private void OnException(DynamicValidatorEventArgs args)
        { 
            var handler = (EventHandler)Events[EventException];
            if (null != handler)
            {
                handler(this, args); 
            }
        } 
        public event EventHandler Exception 
        {
            add { Events.AddHandler(EventException, value); } 
            remove { Events.RemoveHandler(EventException, value); }
        }

        // ContextCreating Event 
        private void OnContextCreating(EntityDataSourceContextCreatingEventArgs e)
        { 
            var handler = (EventHandler)Events[EventContextCreating]; 
            if (null != handler)
            { 
                handler(this, e);
            }
        }
        public event EventHandler ContextCreating 
        {
            add { Events.AddHandler(EventContextCreating, value); } 
            remove { Events.RemoveHandler(EventContextCreating, value); } 
        }
 
        // ContextCreated Event
        private void OnContextCreated(EntityDataSourceContextCreatedEventArgs e)
        {
            var handler = (EventHandler)Events[EventContextCreated]; 
            if (null != handler)
            { 
                handler(this, e); 
            }
        } 
        public event EventHandler ContextCreated
        {
            add { Events.AddHandler(EventContextCreated, value); }
            remove { Events.RemoveHandler(EventContextCreated, value); } 
        }
 
        // ContextDisposing Event 
        private void OnContextDisposing(EntityDataSourceContextDisposingEventArgs e)
        { 
            var handler = (EventHandler)Events[EventContextDisposing];
            if (null != handler)
            {
                handler(this, e); 
            }
        } 
        public event EventHandler ContextDisposing 
        {
            add { Events.AddHandler(EventContextDisposing, value); } 
            remove { Events.RemoveHandler(EventContextDisposing, value); }
        }

        // Selecting Event 
        private void OnSelecting(EntityDataSourceSelectingEventArgs e)
        { 
            var handler = (EventHandler)Events[EventSelecting]; 
            if (null != handler)
            { 
                handler(this, e);
            }
        }
        public event EventHandler Selecting 
        {
            add { Events.AddHandler(EventSelecting, value); } 
            remove { Events.RemoveHandler(EventSelecting, value); } 
        }
 
        // Selected Event
        private void OnSelected(EntityDataSourceSelectedEventArgs e)
        {
            var handler = (EventHandler)Events[EventSelected]; 
            if (null != handler)
            { 
                handler(this, e); 
            }
        } 
        public event EventHandler Selected
        {
            add { Events.AddHandler(EventSelected, value); }
            remove { Events.RemoveHandler(EventSelected, value); } 
        }
 
        // Deleting Event 
        private void OnDeleting(EntityDataSourceChangingEventArgs e)
        { 
            var handler = (EventHandler)Events[EventDeleting];
            if (null != handler)
            {
                handler(this, e); 
            }
        } 
        public event EventHandler Deleting 
        {
            add { Events.AddHandler(EventDeleting, value); } 
            remove { Events.RemoveHandler(EventDeleting, value); }
        }

        // Deleted Event 
        private void OnDeleted(EntityDataSourceChangedEventArgs e)
        { 
            var handler = (EventHandler)Events[EventDeleted]; 
            if (null != handler)
            { 
                handler(this, e);
            }
        }
        public event EventHandler Deleted 
        {
            add { Events.AddHandler(EventDeleted, value); } 
            remove { Events.RemoveHandler(EventDeleted, value); } 
        }
 
        //Inserting Event
        private void OnInserting(EntityDataSourceChangingEventArgs e)
        {
            var handler = (EventHandler)Events[EventInserting]; 
            if (handler != null)
            { 
                handler(this, e); 
            }
        } 
        public event EventHandler Inserting
        {
            add { Events.AddHandler(EventInserting, value); }
            remove { Events.RemoveHandler(EventInserting, value); } 
        }
 
        //Inserted Event 
        private void OnInserted(EntityDataSourceChangedEventArgs e)
        { 
            var handler = (EventHandler)Events[EventInserted];
            if (handler != null)
            {
                handler(this, e); 
            }
        } 
        public event EventHandler Inserted 
        {
            add { Events.AddHandler(EventInserted, value); } 
            remove { Events.RemoveHandler(EventInserted, value); }
        }

        //Updating Event 
        private void OnUpdating(EntityDataSourceChangingEventArgs e)
        { 
            var handler = (EventHandler)Events[EventUpdating]; 
            if (handler != null)
            { 
                handler(this, e);
            }
        }
        public event EventHandler Updating 
        {
            add { Events.AddHandler(EventUpdating, value); } 
            remove { Events.RemoveHandler(EventUpdating, value); } 
        }
 
        //Updated Event
        private void OnUpdated(EntityDataSourceChangedEventArgs e)
        {
            var handler = (EventHandler)Events[EventUpdated]; 
            if (handler != null)
            { 
                handler(this, e); 
            }
        } 
        public event EventHandler Updated
        {
            add { Events.AddHandler(EventUpdated, value); }
            remove { Events.RemoveHandler(EventUpdated, value); } 
        }
 
 
        internal void RaiseChangedEvent()
        { 
            OnDataSourceViewChanged(EventArgs.Empty);
        }

        #endregion Events 

        #region Private Properties 
 
        private StructuralType EntityOSpaceType
        { 
            get
            {
                // If the CSpaceType is not determinable (e.g. DataSource.EntitySetName is not specified),
                // then return null. 
                if (null == EntityCSpaceType)
                { 
                    return null; 
                }
                StructuralType oSpaceType = Context.MetadataWorkspace.GetObjectSpaceType(EntityCSpaceType); 
                return oSpaceType;
            }
        }
 
        // Returns the type for EntityTypeFilter, or
        // null if both EntitySet and EntityTypeFilter are not specified. 
        private EntityType CSpaceFilteredEntityType 
        {
            get 
            {
                EntityType cSpaceType = null;
                if (null == EntitySet)
                { 
                    return null; //read-only scenario in which the EntitySet is not specified on the DataSource
                } 
 
                // Return the type specified in EntityTypeFilter
                if (!String.IsNullOrEmpty(_owner.EntityTypeFilter)) 
                {
                    cSpaceType = (EntityType)Context.MetadataWorkspace.GetType(_owner.EntityTypeFilter, EntitySet.ElementType.NamespaceName, DataSpace.CSpace);
                    if (!EntityDataSourceUtil.IsTypeOrSubtypeOf(EntitySet.ElementType, cSpaceType, Context.MetadataWorkspace.GetItemCollection(DataSpace.CSpace)))
                    { 
                        throw new InvalidOperationException(Strings.EntityDataSourceView_FilteredEntityTypeMustBeDerivableFromEntitySet(_owner.EntityTypeFilter, _owner.EntitySetName));
                    } 
                    return cSpaceType; 
                }
 
                return null;

            }
        } 

        // Returns the actualy EntityCSpaceType to be returned from the query, either via 
        // EntityTypeFilter or via the base type for the EntitySet. 
        private EntityType EntityCSpaceType
        { 
            get
            {
                EntityType cSpaceType = CSpaceFilteredEntityType;
                if (null != cSpaceType) 
                {
                    return cSpaceType; 
                } 

                if (null != EntitySet) 
                {
                    //If EntityDataSource.EntityTypeFilter is not specified, return the base type for the EntitySet.
                    cSpaceType = EntitySet.ElementType;
                } 
                return cSpaceType;
            } 
 
        }
 
        private EntityContainer EntityContainer
        {
            get
            { 
                return Context.MetadataWorkspace.GetEntityContainer(ContainerName, DataSpace.CSpace);
            } 
        } 

        ///  
        /// The EntitySet Associated with this DataSource. If EntityDataSource.EntitySetName is not set, then
        /// This property returns null.
        /// 
        private EntitySet EntitySet 
        {
            get 
            { 
                if (String.IsNullOrEmpty(_owner.EntitySetName))
                { 
                    return null;
                }
                return EntityContainer.GetEntitySetByName(_owner.EntitySetName, /*ignoreCase*/ false);
            } 
        }
 
        private Type EntityClrType 
        {
            get 
            {
                ObjectItemCollection objectItemCollection =
                    (ObjectItemCollection)(Context.MetadataWorkspace.GetItemCollection(DataSpace.OSpace));
                Type clrType = objectItemCollection.GetClrType(EntityOSpaceType); 
                return clrType;
            } 
        } 

        private ObjectContext Context 
        {
            get
            {
                Debug.Assert(null != _ctx, "The context hasn't yet been constructed"); 
                return _ctx;
            } 
        } 

        private ReadOnlyMetadataCollection KeyMembers 
        {
            get
            {
                if (null == _keyMembers) 
                {
                    EntityContainer entityContainer = Context.MetadataWorkspace.GetEntityContainer(ContainerName, DataSpace.CSpace); 
                    EntitySet entitySet = entityContainer.GetEntitySetByName(_owner.EntitySetName, false); 

                    _keyMembers = ((EntityType)(entitySet.ElementType)).KeyMembers; 
                }
                return _keyMembers;
            }
        } 

        private string ContainerName 
        { 
            get
            { 
                if (!string.IsNullOrEmpty(_owner.DefaultContainerName))
                {
                    return _owner.DefaultContainerName;
                } 
                if (!string.IsNullOrEmpty(Context.DefaultContainerName))
                { 
                    return Context.DefaultContainerName; 
                }
                throw new InvalidOperationException(Strings.EntityDataSourceView_ContainerNameMustBeSpecified); 
            }
        }

        #endregion Private Properties 

        #region private getters 
 
        #endregion private getters
 
        #region IStateManager implementation
        bool IStateManager.IsTrackingViewState
        {
            get { return _tracking; } 
        }
        void IStateManager.LoadViewState(object savedState) 
        { 
            if (null != savedState)
            { 
                var state = (Pair)savedState;
                _disableUpdates = (bool)state.First;
                _originalProperties = (Dictionary)state.Second;
            } 
        }
 
        object IStateManager.SaveViewState() 
        {
            StoreOriginalPropertiesIntoViewState(); 
            return new Pair(_disableUpdates, _originalProperties);
        }
        void IStateManager.TrackViewState()
        { 
            _tracking = true;
        } 
        #endregion 

        #region Utilities and Error Checking 

        private void AddSupportedCapabilities(DataSourceSelectArguments arguments)
        {
            if (CanSort) 
            {
                arguments.AddSupportedCapabilities(DataSourceCapabilities.Sort); 
            } 
            if (CanPage)
            { 
                arguments.AddSupportedCapabilities(DataSourceCapabilities.Page);
                arguments.AddSupportedCapabilities(DataSourceCapabilities.RetrieveTotalRowCount);
            }
        } 

        internal void ValidateEntitySetName() 
        { 
            EntityContainer entityContainer = Context.MetadataWorkspace.GetEntityContainer(ContainerName, DataSpace.CSpace);
            EntitySet entitySet; 
            if (!entityContainer.TryGetEntitySetByName(_owner.EntitySetName, /*ignoreCase*/false, out entitySet))
            {
                throw new InvalidOperationException(Strings.EntityDataSourceView_EntitySetDoesNotExistOnTheContainer(_owner.EntitySetName));
            } 
        }
 
        private void ValidateContainerName() 
        {
            EntityContainer container; 
            if (!Context.MetadataWorkspace.TryGetEntityContainer(ContainerName, DataSpace.CSpace, out container))
            {
                throw new InvalidOperationException(Strings.EntityDataSourceView_ContainerNameDoesNotExistOnTheContext(ContainerName));
            } 
        }
 
        // From LinqDataSourceHelper. Timestamp columns (of type byte[]) are of type IEnumerable. 
        // This routine compares all elements of the IEnumerable.
        private static bool EnumerableContentEquals(IEnumerable enumerableA, IEnumerable enumerableB) 
        {
            IEnumerator enumeratorA = enumerableA.GetEnumerator();
            IEnumerator enumeratorB = enumerableB.GetEnumerator();
            while (enumeratorA.MoveNext()) 
            {
                if (!enumeratorB.MoveNext()) 
                    return false; 
                object itemA = enumeratorA.Current;
                object itemB = enumeratorB.Current; 
                if (itemA == null)
                {
                    if (itemB != null)
                        return false; 
                }
                else if (!itemA.Equals(itemB)) 
                    return false; 
            }
            if (enumeratorB.MoveNext()) 
                return false;
            return true;
        }
 
        // This routine modified from System.Web.Ui.WebControls.
        private static object Parameter_GetValue(object value, WebControlParameterProxy parameter, bool ignoreNullableTypeChanges) 
        { 
            // Convert.ChangeType() throws if you attempt to convert to DBNull, so we have to special case it.
            if (parameter.TypeCode == TypeCode.DBNull) 
            {
                return DBNull.Value;
            }
 
            // Get the value and convert it to the default value if it is null
            if (parameter.ConvertEmptyStringToNull) 
            { 
                string stringValue = value as string;
                if ((stringValue != null) && (stringValue.Length == 0)) 
                {
                    value = null;
                }
 
            }
 
            if (value == null) // Fill it with values from referenceParameters 
            {
                // Use the parameter value if it is non-null 
                if (!parameter.HasValue)
                {
                    return value;
                } 

                object parameterValue = parameter.Value; 
                string valueString = parameterValue as String; 
                if (parameter.TypeCode == TypeCode.String && parameter.ConvertEmptyStringToNull && String.IsNullOrEmpty(valueString))
                { 
                    parameterValue = null;
                }

                if (null == parameterValue) 
                {
                    return null; 
                } 
                value = parameterValue;
            } 

            Debug.Assert(value != null, "Value should not be null at this point.");

            if (parameter.TypeCode == TypeCode.Object || parameter.TypeCode == TypeCode.Empty) 
            {
                return value; 
            } 

            // For ObjectDataSource we special-case Nullable and do nothing because these 
            // types will get converted when we actually call the method.
            if (ignoreNullableTypeChanges)
            {
                Type valueType = value.GetType(); 
                if (valueType.IsGenericType && (valueType.GetGenericTypeDefinition() == typeof(Nullable<>)))
                { 
                    return value; 
                }
            } 
            return value = Convert.ChangeType(value, parameter.TypeCode, CultureInfo.CurrentCulture); ;
        }

 
        #endregion Utilities
 
        //public override void Delete(IDictionary keys, IDictionary oldValues, DataSourceViewOperationCallback callback){} 
        //public override void Insert(IDictionary values, DataSourceViewOperationCallback callback){}
        //public override void Select(DataSourceSelectArguments arguments, DataSourceViewSelectCallback callback){} 
        //public override void Update(IDictionary keys, IDictionary values, IDictionary oldValues, DataSourceViewOperationCallback callback){}

    }
} 

// 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