Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / DataEntity / System / Data / Objects / ObjectViewFactory.cs / 1599186 / ObjectViewFactory.cs
//---------------------------------------------------------------------- //// Copyright (c) Microsoft Corporation. All rights reserved. // // // @owner [....] // @backupOwner [....] //--------------------------------------------------------------------- using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Data.Common; using System.Data.Metadata; using System.Data.Metadata.Edm; using System.Data.Objects.DataClasses; using System.Data.Objects.Internal; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; namespace System.Data.Objects { ////// Creates instances of ObjectView that provide a binding list for ObjectQuery results and EntityCollections. /// ////// The factory methods construct an ObjectView whose generic type parameter (and typed of elements in the binding list) /// is of the same type or a more specific derived type of the generic type of the ObjectQuery or EntityCollection. /// The EDM type of the query results or EntityType or the EntityCollection is examined to determine /// the appropriate type to be used. /// For example, if you have an ObjectQuery whose generic type is "object", but the EDM result type of the Query maps /// to the CLR type "Customer", then the ObjectView returned will specify a generic type of "Customer", and not "object". /// internal static class ObjectViewFactory { // References to commonly-used generic type definitions. private static readonly Type genericObjectViewType = typeof(ObjectView<>); private static readonly Type genericObjectViewDataInterfaceType = typeof(IObjectViewData<>); private static readonly Type genericObjectViewQueryResultDataType = typeof(ObjectViewQueryResultData<>); private static readonly Type genericObjectViewEntityCollectionDataType = typeof(ObjectViewEntityCollectionData<,>); ////// Return a list suitable for data binding using the supplied query results. /// ////// CLR type of query result elements declared by the caller. /// /// /// The EDM type of the query results, used as the primary means of determining the /// CLR type of list returned by this method. /// /// /// IEnumerable used to enumerate query results used to populate binding list. /// Must not be null. /// /// ///associated with the query from which results were obtained. /// Must not be null. /// /// /// True to prevent modifications to the binding list built from the query result; otherwise false. /// Note that other conditions may prevent the binding list from being modified, so a value of false /// supplied for this parameter doesn't necessarily mean that the list will be writable. /// /// /// If the query results are composed of entities that only exist in a single , /// the value of this parameter is the single EntitySet. /// Otherwise the value of this parameter should be null. /// /// /// [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] internal static IBindingList CreateViewForQuerythat is suitable for data binding. /// (TypeUsage elementEdmTypeUsage, IEnumerable 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 (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 viewData = new ObjectViewQueryResultData ((IEnumerable)queryResults, objectContext, forceReadOnly, singleEntitySet); objectView = new ObjectView (viewData, eventDataSource); } else if (clrElementType == null) { ObjectViewQueryResultData viewData = new ObjectViewQueryResultData ((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; } /// /// Return a list suitable for data binding using the supplied EntityCollection /// ////// CLR type of the elements of the EntityCollection. /// /// /// 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. /// /// /// The EntityCollection from which a binding list is created. /// ////// [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] internal static IBindingList CreateViewForEntityCollectionthat is suitable for data binding. /// (EntityType entityType, EntityCollection 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 (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 viewData = new ObjectViewEntityCollectionData (entityCollection); objectView = new ObjectView (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 ) }, 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; } /// /// Create an ObjectView using reflection. /// /// Type to be used for the ObjectView's generic type parameter. /// The type of class that implements the IObjectViewData to be used by the ObjectView. /// The IObjectViewData to be used by the ObjectView to access the binding list. /// Event source used by ObjectView for entity and membership changes. ///[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] private static IBindingList CreateObjectView(Type clrElementType, Type objectViewDataType, object viewData, object eventDataSource) { Type objectViewType = genericObjectViewType.MakeGenericType(clrElementType); Type[] viewDataInterfaces = objectViewDataType.FindInterfaces((Type type, object unusedFilter) => type.Name == genericObjectViewDataInterfaceType.Name, null); Debug.Assert(viewDataInterfaces.Length == 1, "Could not find IObjectViewData interface definition for ObjectViewQueryResultData ."); ConstructorInfo viewConstructor = objectViewType.GetConstructor(BindingFlags.Instance | BindingFlags.NonPublic, null, new Type[] { viewDataInterfaces[0], typeof(object) }, null); Debug.Assert(viewConstructor != null, "ObjectView constructor not found. Please ensure constructor signature is correct."); // Create ObjectView instance return (IBindingList)viewConstructor.Invoke(new object[] { viewData, eventDataSource }); } /// /// Map the supplied TypeUsage to O-Space. /// /// /// The TypeUsage to be mapped to O-Space. Should either be associated with C-Space or O-Space. /// /// /// ObjectContext used to perform type mapping. /// ///private static TypeUsage GetOSpaceTypeUsage(TypeUsage typeUsage, ObjectContext objectContext) { TypeUsage ospaceTypeUsage; if (typeUsage == null || typeUsage.EdmType == null) { ospaceTypeUsage = null; } else { if (typeUsage.EdmType.DataSpace == DataSpace.OSpace) { ospaceTypeUsage = typeUsage; } else { Debug.Assert(typeUsage.EdmType.DataSpace == DataSpace.CSpace, String.Format(System.Globalization.CultureInfo.InvariantCulture, "Expected EdmType.DataSpace to be C-Space, but instead it is {0}.", typeUsage.EdmType.DataSpace.ToString())); // The ObjectContext is needed to map the EDM TypeUsage from C-Space to O-Space. if (objectContext == null) { ospaceTypeUsage = null; } else { objectContext.EnsureMetadata(); ospaceTypeUsage = objectContext.Perspective.MetadataWorkspace.GetOSpaceTypeUsage(typeUsage); } } } return ospaceTypeUsage; } /// /// Determine CLR Type to be exposed for data binding using the supplied EDM item type. /// ////// CLR element type declared by the caller. /// /// There is no requirement that this method return the same type, or a type compatible with the declared type; /// it is merely a suggestion as to which type might be used. /// /// /// The EDM O-Space type of the items in a particular query result. /// ////// private static Type GetClrTypeinstance that represents the CLR type that corresponds to the supplied EDM item type; /// or null if the EDM type does not map to a CLR type. /// Null is returned in the case where is a , /// and no CLR type mapping is specified in the RowType metadata. /// (EdmType ospaceEdmType) { Type clrType; // EDM RowTypes are generally represented by CLR MaterializedDataRecord types // that need special handling to properly expose the properties available for binding (using ICustomTypeDescriptor and ITypedList implementations, for example). // // However, if the RowType has InitializerMetadata with a non-null CLR Type, // that CLR type should be used to determine the properties available for binding. if (ospaceEdmType.BuiltInTypeKind == BuiltInTypeKind.RowType) { RowType itemRowType = (RowType)ospaceEdmType; if (itemRowType.InitializerMetadata != null && itemRowType.InitializerMetadata.ClrType != null) { clrType = itemRowType.InitializerMetadata.ClrType; } else { // If the generic parameter TElement is not exactly a data record type or object type, // use it as the CLR type. Type elementType = typeof(TElement); if (typeof(IDataRecord).IsAssignableFrom(elementType) || elementType == typeof(object)) { // No CLR type mapping exists for this RowType. clrType = null; } else { clrType = typeof(TElement); } } } else { clrType = ospaceEdmType.ClrType; // If the CLR type cannot be determined from the EDM type, // fallback to the element type declared by the caller. if (clrType == null) { clrType = typeof(TElement); } } return clrType; } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- Parameter.cs
- EventRecord.cs
- DeviceContexts.cs
- BuildDependencySet.cs
- SiteMapNodeItemEventArgs.cs
- Message.cs
- TableLayoutStyleCollection.cs
- MouseActionValueSerializer.cs
- BaseCollection.cs
- SkewTransform.cs
- XmlElementList.cs
- SqlCacheDependencyDatabase.cs
- HttpSocketManager.cs
- AddInIpcChannel.cs
- TransformProviderWrapper.cs
- IOThreadTimer.cs
- _SslSessionsCache.cs
- ManipulationPivot.cs
- DeferredRunTextReference.cs
- WinFormsSecurity.cs
- MultiView.cs
- XhtmlBasicLinkAdapter.cs
- FileDialogCustomPlacesCollection.cs
- BamlRecordHelper.cs
- EntityType.cs
- TableLayout.cs
- _FtpControlStream.cs
- BamlLocalizabilityResolver.cs
- VariableAction.cs
- ImagingCache.cs
- ViewEvent.cs
- LogicalExpr.cs
- Missing.cs
- DataGridPagerStyle.cs
- OdbcConnection.cs
- FullTrustAssembly.cs
- ShaderRenderModeValidation.cs
- MembershipSection.cs
- RayHitTestParameters.cs
- SqlOuterApplyReducer.cs
- EntityKeyElement.cs
- HandleInitializationContext.cs
- XmlWriterSettings.cs
- TemporaryBitmapFile.cs
- ProgressiveCrcCalculatingStream.cs
- ClientScriptItemCollection.cs
- SolidColorBrush.cs
- SuppressMergeCheckAttribute.cs
- CodeGenerator.cs
- ControlsConfig.cs
- RectKeyFrameCollection.cs
- Transform.cs
- BaseTemplateParser.cs
- GridProviderWrapper.cs
- StreamAsIStream.cs
- PageThemeParser.cs
- GreenMethods.cs
- HostedTcpTransportManager.cs
- MoveSizeWinEventHandler.cs
- FilteredSchemaElementLookUpTable.cs
- AnonymousIdentificationModule.cs
- DocumentSequenceHighlightLayer.cs
- TextRenderer.cs
- CopyCodeAction.cs
- Reference.cs
- httpserverutility.cs
- NamespaceEmitter.cs
- LeftCellWrapper.cs
- SchemeSettingElement.cs
- ProfileServiceManager.cs
- LocalizableResourceBuilder.cs
- PropertyDescriptorGridEntry.cs
- httpstaticobjectscollection.cs
- DBProviderConfigurationHandler.cs
- RelatedCurrencyManager.cs
- future.cs
- CompositeCollectionView.cs
- WsrmFault.cs
- StoryFragments.cs
- IOThreadTimer.cs
- PeerPresenceInfo.cs
- TextEffect.cs
- TargetPerspective.cs
- SessionStateContainer.cs
- ThrowOnMultipleAssignment.cs
- RuntimeHandles.cs
- CompleteWizardStep.cs
- FontDriver.cs
- TextContainerChangedEventArgs.cs
- XPathDocument.cs
- CompositeCollection.cs
- ContextBase.cs
- PenCursorManager.cs
- DbExpressionBuilder.cs
- TableHeaderCell.cs
- DbProviderFactory.cs
- DataSysAttribute.cs
- XamlReaderHelper.cs
- WeakEventManager.cs
- NotificationContext.cs