Esempio n. 1
0
        public void Remove_throws_for_null_argument()
        {
            var mockEntityCollection = DataClasses.MockHelper.CreateMockEntityCollection <object>(null).Object;
            var objectView           = new ObjectView <object>(
                new ObjectViewEntityCollectionData <object, object>(mockEntityCollection), mockEntityCollection);

            Assert.Equal(
                "value",
                Assert.Throws <ArgumentNullException>(
                    () => ((IList)objectView).Remove(null)).ParamName);
        }
        /// <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);
        }
        /// <summary>
        ///     Return a list suitable for data binding using the supplied EntityCollection
        /// </summary>
        /// <typeparam name="TElement"> CLR type of the elements of the EntityCollection. </typeparam>
        /// <param name="entityType"> The EntityType of the elements in the collection. This should either be the same as the EntityType that corresponds to the CLR TElement type, or a EntityType derived from the declared EntityCollection element type. </param>
        /// <param name="entityCollection"> The EntityCollection from which a binding list is created. </param>
        /// <returns>
        ///     <see cref="IBindingList" /> that is suitable for data binding.
        /// </returns>
        internal static IBindingList CreateViewForEntityCollection <TElement>(
            EntityType entityType, EntityCollection <TElement> entityCollection)
            where TElement : class
        {
            Type clrElementType         = null;
            var  entityTypeUsage        = entityType == null ? null : TypeUsage.Create(entityType);
            var  ospaceElementTypeUsage = GetOSpaceTypeUsage(entityTypeUsage, entityCollection.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);
            }
            else
            {
                clrElementType = GetClrType <TElement>(ospaceElementTypeUsage.EdmType);

                // A null clrElementType is returned by GetClrType if the EDM type is a RowType with no specific CLR type mapping.
                // This should not happen when working with EntityCollections, but if it does, fallback to TEntityRef type.
                Debug.Assert(clrElementType != null, "clrElementType has unexpected value of null.");

                if (clrElementType == null)
                {
                    clrElementType = typeof(TElement);
                }
            }

            IBindingList objectView;

            // 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 ObjectViewEntityCollectionData <TElement, TElement>(entityCollection);
                objectView = new ObjectView <TElement>(viewData, entityCollection);
            }
            else
            {
                if (!typeof(TElement).IsAssignableFrom(clrElementType))
                {
                    throw EntityUtil.ValueInvalidCast(clrElementType, typeof(TElement));
                }

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

                var objectViewDataType = _genericObjectViewEntityCollectionDataType.MakeGenericType(clrElementType, typeof(TElement));

                var viewDataConstructor = objectViewDataType.GetConstructor(
                    BindingFlags.Instance | BindingFlags.NonPublic,
                    null,
                    new[] { typeof(EntityCollection <TElement>) },
                    null);

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

                // Create ObjectViewEntityCollectionData instance
                var viewData = viewDataConstructor.Invoke(new object[] { entityCollection });

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

            return(objectView);
        }