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
- X509CertificateCollection.cs
- DispatcherProcessingDisabled.cs
- BinHexDecoder.cs
- FragmentNavigationEventArgs.cs
- Marshal.cs
- DataGridViewImageColumn.cs
- OracleCommandSet.cs
- HtmlGenericControl.cs
- SymLanguageType.cs
- LoopExpression.cs
- EncryptedData.cs
- ToolStripButton.cs
- Activity.cs
- DataFormats.cs
- CharUnicodeInfo.cs
- SpnegoTokenProvider.cs
- SemanticResolver.cs
- LayoutTableCell.cs
- SmtpClient.cs
- BitmapVisualManager.cs
- AsyncWaitHandle.cs
- ProtocolsConfigurationEntry.cs
- ProfileServiceManager.cs
- OperandQuery.cs
- UserControlFileEditor.cs
- VisualStyleTypesAndProperties.cs
- WmlFormAdapter.cs
- unitconverter.cs
- XmlSchemaObjectCollection.cs
- JulianCalendar.cs
- InvalidPropValue.cs
- DataObjectAttribute.cs
- XmlSchemaExternal.cs
- InitializerFacet.cs
- PostBackOptions.cs
- MemberRelationshipService.cs
- LineBreak.cs
- XmlObjectSerializer.cs
- sqlmetadatafactory.cs
- AssemblyBuilderData.cs
- SQLInt64Storage.cs
- QueryGenerator.cs
- _WinHttpWebProxyDataBuilder.cs
- AggregateNode.cs
- BitmapEffectDrawing.cs
- NegotiationTokenAuthenticatorStateCache.cs
- DataGridViewCellStyleChangedEventArgs.cs
- MatrixUtil.cs
- RotateTransform3D.cs
- WhitespaceRuleLookup.cs
- ItemMap.cs
- UidManager.cs
- ConditionCollection.cs
- NamedPipeHostedTransportConfiguration.cs
- NamespaceDecl.cs
- DataPagerFieldItem.cs
- Converter.cs
- LiteralSubsegment.cs
- ControlHelper.cs
- WinEventQueueItem.cs
- ButtonChrome.cs
- PropertySourceInfo.cs
- EntityDataSourceValidationException.cs
- WebPartZone.cs
- Fx.cs
- HtmlFormParameterReader.cs
- ConfigPathUtility.cs
- TrustManager.cs
- MediaPlayerState.cs
- IEnumerable.cs
- TextBreakpoint.cs
- SqlRowUpdatedEvent.cs
- DateTimeOffset.cs
- SortedDictionary.cs
- TreeNodeMouseHoverEvent.cs
- XmlChildNodes.cs
- SqlProfileProvider.cs
- Int64.cs
- ADMembershipProvider.cs
- DelegateSerializationHolder.cs
- WebPartEditorApplyVerb.cs
- XmlMembersMapping.cs
- CellIdBoolean.cs
- DataTableNameHandler.cs
- XmlLinkedNode.cs
- KnownTypesHelper.cs
- ComplexObject.cs
- ColumnHeader.cs
- AuthenticatedStream.cs
- Utils.cs
- TableHeaderCell.cs
- ObjectSet.cs
- KnowledgeBase.cs
- HwndMouseInputProvider.cs
- SQLBinaryStorage.cs
- ProcessHost.cs
- LexicalChunk.cs
- RequestCacheValidator.cs
- DBAsyncResult.cs
- TrackingLocation.cs