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); }
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); }