Exemplo n.º 1
0
        internal static IBindingList CreateViewForQuery <TElement>(TypeUsage elementEdmTypeUsage, IEnumerable <TElement> queryResults, ObjectContext objectContext, bool forceReadOnly, EntitySet singleEntitySet)
        {
            EntityUtil.CheckArgumentNull(queryResults, "queryResults");
            EntityUtil.CheckArgumentNull(objectContext, "objectContext");

            Type      clrElementType         = null;
            TypeUsage 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))
            {
                ObjectViewQueryResultData <TElement> viewData = new ObjectViewQueryResultData <TElement>((IEnumerable)queryResults, objectContext, forceReadOnly, singleEntitySet);

                objectView = new ObjectView <TElement>(viewData, eventDataSource);
            }
            else if (clrElementType == null)
            {
                ObjectViewQueryResultData <DbDataRecord> viewData = new ObjectViewQueryResultData <DbDataRecord>((IEnumerable)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.

                Type objectViewDataType = genericObjectViewQueryResultDataType.MakeGenericType(clrElementType);

                ConstructorInfo viewDataConstructor = objectViewDataType.GetConstructor(BindingFlags.Instance | BindingFlags.NonPublic,
                                                                                        null,
                                                                                        new Type[] { 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
                object viewData = viewDataConstructor.Invoke(new object[] { queryResults, objectContext, forceReadOnly, singleEntitySet });

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

            return(objectView);
        }
Exemplo n.º 2
0
        internal static IBindingList CreateViewForEntityCollection <TElement>(EntityType entityType, EntityCollection <TElement> entityCollection)
            where TElement : class
        {
            Type      clrElementType         = null;
            TypeUsage entityTypeUsage        = entityType == null ? null : TypeUsage.Create(entityType);
            TypeUsage 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))
            {
                ObjectViewEntityCollectionData <TElement, TElement> 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.

                Type objectViewDataType = genericObjectViewEntityCollectionDataType.MakeGenericType(clrElementType, typeof(TElement));

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

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

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

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

            return(objectView);
        }