Beispiel #1
0
        internal ObjectViewQueryResultData(
            IEnumerable queryResults,
            ObjectContext objectContext,
            bool forceReadOnlyList,
            EntitySet entitySet)
        {
            bool flag = ObjectViewQueryResultData <TElement> .IsEditable(typeof(TElement));

            this._objectContext = objectContext;
            this._entitySet     = entitySet;
            this._canEditItems  = flag;
            this._canModifyList = !forceReadOnlyList && flag && this._objectContext != null;
            this._bindingList   = new System.Collections.Generic.List <TElement>();
            foreach (TElement queryResult in queryResults)
            {
                this._bindingList.Add(queryResult);
            }
        }
        /// <summary>
        ///     Return a list suitable for data binding using the supplied query results.
        /// </summary>
        /// <typeparam name="TElement"> CLR type of query result elements declared by the caller. </typeparam>
        /// <param name="elementEdmTypeUsage"> The EDM type of the query results, used as the primary means of determining the CLR type of list returned by this method. </param>
        /// <param name="queryResults"> IEnumerable used to enumerate query results used to populate binding list. Must not be null. </param>
        /// <param name="objectContext">
        ///     <see cref="ObjectContext" /> associated with the query from which results were obtained. Must not be null.
        /// </param>
        /// <param name="forceReadOnly">
        ///     <b>True</b> to prevent modifications to the binding list built from the query result; otherwise <b>false</b> . Note that other conditions may prevent the binding list from being modified, so a value of <b>false</b> supplied for this parameter doesn't necessarily mean that the list will be writable.
        /// </param>
        /// <param name="singleEntitySet">
        ///     If the query results are composed of entities that only exist in a single
        ///     <see
        ///         cref="EntitySet" />
        ///     , the value of this parameter is the single EntitySet. Otherwise the value of this parameter should be null.
        /// </param>
        /// <returns>
        ///     <see cref="IBindingList" /> that is suitable for data binding.
        /// </returns>
        internal static IBindingList CreateViewForQuery <TElement>(
            TypeUsage elementEdmTypeUsage, IEnumerable <TElement> queryResults, ObjectContext objectContext, bool forceReadOnly,
            EntitySet singleEntitySet)
        {
            DebugCheck.NotNull(queryResults);
            DebugCheck.NotNull(objectContext);

            Type clrElementType         = null;
            var  ospaceElementTypeUsage = GetOSpaceTypeUsage(elementEdmTypeUsage, objectContext);

            // Map the O-Space EDM type to a CLR type.
            // If the mapping is unsuccessful, fallback to TElement type.
            if (ospaceElementTypeUsage == null)
            {
                clrElementType = typeof(TElement);
            }
            {
                clrElementType = GetClrType <TElement>(ospaceElementTypeUsage.EdmType);
            }

            IBindingList objectView;
            object       eventDataSource = objectContext.ObjectStateManager;

            // If the clrElementType matches the declared TElement type, optimize the construction of the ObjectView
            // by avoiding a reflection-based instantiation.
            if (clrElementType == typeof(TElement))
            {
                var viewData = new ObjectViewQueryResultData <TElement>(queryResults, objectContext, forceReadOnly, singleEntitySet);

                objectView = new ObjectView <TElement>(viewData, eventDataSource);
            }
            else if (clrElementType == null)
            {
                var viewData = new ObjectViewQueryResultData <DbDataRecord>(queryResults, objectContext, true, null);
                objectView = new DataRecordObjectView(viewData, eventDataSource, (RowType)ospaceElementTypeUsage.EdmType, typeof(TElement));
            }
            else
            {
                if (!typeof(TElement).IsAssignableFrom(clrElementType))
                {
                    throw EntityUtil.ValueInvalidCast(clrElementType, typeof(TElement));
                }

                // Use reflection to create an instance of the generic ObjectView and ObjectViewQueryResultData classes,
                // using clrElementType as the value of TElement generic type parameter for both classes.

                var objectViewDataType = _genericObjectViewQueryResultDataType.MakeGenericType(clrElementType);

                var viewDataConstructor = objectViewDataType.GetConstructor(
                    BindingFlags.Instance | BindingFlags.NonPublic,
                    null,
                    new[] { typeof(IEnumerable), typeof(ObjectContext), typeof(bool), typeof(EntitySet) },
                    null);

                Debug.Assert(
                    viewDataConstructor != null,
                    "ObjectViewQueryResultData constructor not found. Please ensure constructor signature is correct.");

                // Create ObjectViewQueryResultData instance
                var viewData = viewDataConstructor.Invoke(new object[] { queryResults, objectContext, forceReadOnly, singleEntitySet });

                // Create ObjectView instance
                objectView = CreateObjectView(clrElementType, objectViewDataType, viewData, eventDataSource);
            }

            return(objectView);
        }