Code:
/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / Orcas / QFE / ndp / fx / src / DataEntity / System / Data / Query / InternalTrees / columnmapfactory.cs / 1 / columnmapfactory.cs
//------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // // @owner [....], [....] //----------------------------------------------------------------------------- using System.Data.Common; using System.Data.Mapping; using System.Data.Metadata.Edm; using System.Diagnostics; using System.Collections.Generic; namespace System.Data.Query.InternalTrees { ////// Factory methods for prescriptive column map patterns (includes default /// column maps for -- soon to be -- public materializer services and function /// mappings). /// internal static class ColumnMapFactory { ////// Creates a column map for the given reader and function mapping. /// internal static CollectionColumnMap CreateFunctionImportEntityColumnMap(DbDataReader storeDataReader, FunctionImportMapping mapping, EntitySet entitySet, EntityType baseEntityType) { if (mapping.NormalizedEntityTypeMappings.Count == 0) // no explicit mapping; use default non-polymorphic reader { // if there is no mapping, create default mapping to root entity type Debug.Assert(!baseEntityType.Abstract, "mapping loader must verify abstract types have explicit mapping"); return CreateColumnMapFromReaderAndType(storeDataReader, baseEntityType, entitySet); } // Generate column maps for all discriminators ScalarColumnMap[] discriminatorColumns = CreateDiscriminatorColumnMaps(storeDataReader, mapping); // Generate default maps for all mapped entity types var mappedEntityTypes = new HashSet(mapping.MappedEntityTypes); mappedEntityTypes.Add(baseEntityType); // make sure the base type is represented Dictionary typeChoices = new Dictionary (mappedEntityTypes.Count); ColumnMap[] baseTypeColumnMaps = null; foreach (EntityType entityType in mappedEntityTypes) { ColumnMap[] propertyColumnMaps = GetColumnMapsForType(storeDataReader, entityType); EntityColumnMap entityColumnMap = CreateEntityTypeElementColumnMap(storeDataReader, entityType, entitySet, propertyColumnMaps); typeChoices.Add(entityType, entityColumnMap); if (entityType == baseEntityType) { baseTypeColumnMaps = propertyColumnMaps; } } // NOTE: We don't have a null sentinel here, because the stored proc won't // return one anyway; we'll just presume the data's always there. MultipleDiscriminatorPolymorphicColumnMap polymorphicMap = new MultipleDiscriminatorPolymorphicColumnMap(TypeUsage.Create(baseEntityType), baseEntityType.Name, baseTypeColumnMaps, discriminatorColumns, typeChoices, mapping.Discriminate); CollectionColumnMap collection = new SimpleCollectionColumnMap(baseEntityType.GetCollectionType().TypeUsage, baseEntityType.Name, polymorphicMap, null, null, null); return collection; } /// /// Build the collectionColumnMap from a store datareader, a type and an entitySet. /// /// /// /// ///private static CollectionColumnMap CreateColumnMapFromReaderAndType(DbDataReader storeDataReader, EdmType edmType, EntitySet entitySet) { if (!Helper.IsEntityType(edmType) && null != entitySet) { throw EntityUtil.EntitySetForNonEntityType(); } // Next, build the ColumnMap directly from the edmType and entitySet provided. ColumnMap[] propertyColumnMaps = GetColumnMapsForType(storeDataReader, edmType); ColumnMap elementColumnMap = null; // NOTE: We don't have a null sentinel here, because the stored proc won't // return one anyway; we'll just presume the data's always there. if (Helper.IsRowType(edmType)) { elementColumnMap = new RecordColumnMap(TypeUsage.Create(edmType), edmType.Name, propertyColumnMaps, null); } else if (Helper.IsComplexType(edmType)) { elementColumnMap = new ComplexTypeColumnMap(TypeUsage.Create(edmType), edmType.Name, propertyColumnMaps, null); } else if (Helper.IsPrimitiveType(edmType)) { if (storeDataReader.FieldCount != 1) { throw EntityUtil.CommandExecutionDataReaderFieldCountForPrimitiveType(); } elementColumnMap = new ScalarColumnMap(TypeUsage.Create(edmType), edmType.Name, 0, 0); } else if (Helper.IsEntityType(edmType)) { elementColumnMap = CreateEntityTypeElementColumnMap(storeDataReader, edmType, entitySet, propertyColumnMaps); } else { Debug.Assert(false, "unexpected edmType?"); } CollectionColumnMap collection = new SimpleCollectionColumnMap(edmType.GetCollectionType().TypeUsage, edmType.Name, elementColumnMap, null, null, null); return collection; } /// /// Build the entityColumnMap from a store datareader, a type and an entitySet and /// a list ofproperties. /// /// /// /// /// ///private static EntityColumnMap CreateEntityTypeElementColumnMap(DbDataReader storeDataReader, EdmType edmType, EntitySet entitySet, ColumnMap[] propertyColumnMaps) { // If the consumer didn't specify an entity set, we just dummy up // the no-entity-identity-entity-set. SimpleEntityIdentity simpleEntityIdentity = EntityIdentity.NoEntityIdentity; if (null != entitySet) { EntityType entityType = (EntityType)entitySet.ElementType; Debug.Assert(entityType.IsAssignableFrom(edmType), "edmType, entitySet.ElementType mismatch!"); // If they've requested an EntitySet, then we need to construct a // SimpleEntityIdentity for that EntitySet. The tricky part here is // that the KeyColumns list must point at the same ColumnMap(s) that // the properties list points to, so we build a quick array of // ColumnMap(s) that are indexed by their ordinal; then we can walk // the list of keyMembers, and find the ordinal in the reader, and // pick the same ColumnMap for it. // Build the ordinal -> ColumnMap index ColumnMap[] ordinalToColumnMap = new ColumnMap[storeDataReader.FieldCount]; foreach (ColumnMap propertyColumnMap in propertyColumnMaps) { int ordinal = ((ScalarColumnMap)propertyColumnMap).ColumnPos; ordinalToColumnMap[ordinal] = propertyColumnMap; } // Now build the list of KeyColumns; IList keyMembers = entityType.KeyMembers; SimpleColumnMap[] keyColumns = new SimpleColumnMap[keyMembers.Count]; int keyMemberIndex = 0; foreach (EdmMember keyMember in keyMembers) { int keyOrdinal = GetMemberOrdinalFromReader(storeDataReader, keyMember); Debug.Assert(keyOrdinal >= 0, "keyMember for entity is not found by name in the data reader?"); ColumnMap keyColumnMap = ordinalToColumnMap[keyOrdinal]; Debug.Assert(null != keyColumnMap, "keyMember for entity isn't in properties collection for the entity?"); keyColumns[keyMemberIndex] = (SimpleColumnMap)keyColumnMap; keyMemberIndex++; } // And finally, the SimpleEntityIdentity... simpleEntityIdentity = new SimpleEntityIdentity(entitySet, keyColumns); } EntityColumnMap result = new EntityColumnMap(TypeUsage.Create(edmType), edmType.Name, propertyColumnMaps, simpleEntityIdentity); return result; } /// /// For a given edmType, build an array of scalarColumnMaps that map to the columns /// in the store datareader provided. Note that we're hooking things up by name, not /// by ordinal position. /// /// /// ///private static ColumnMap[] GetColumnMapsForType(DbDataReader storeDataReader, EdmType edmType) { // First get the list of properties; NOTE: we need to hook up the column by name, // not by position. IBaseList members = TypeHelpers.GetAllStructuralMembers(edmType); ColumnMap[] propertyColumnMaps = new ColumnMap[members.Count]; int index = 0; foreach (EdmMember member in members) { Debug.Assert(Helper.IsPrimitiveType(member.TypeUsage.EdmType), "non-primitive type?"); int ordinal = GetMemberOrdinalFromReader(storeDataReader, member); propertyColumnMaps[index] = new ScalarColumnMap(member.TypeUsage, member.Name, 0, ordinal); index++; } return propertyColumnMaps; } private static ScalarColumnMap[] CreateDiscriminatorColumnMaps(DbDataReader storeDataReader, FunctionImportMapping mapping) { // choose an arbitrary type for discriminator columns -- the type is not // actually statically known EdmType discriminatorType = MetadataItem.EdmProviderManifest.GetPrimitiveType(PrimitiveTypeKind.String); TypeUsage discriminatorTypeUsage = TypeUsage.Create(discriminatorType); ScalarColumnMap[] discriminatorColumns = new ScalarColumnMap[mapping.DiscriminatorColumns.Count]; for (int i = 0; i < discriminatorColumns.Length; i++) { string columnName = mapping.DiscriminatorColumns[i]; ScalarColumnMap columnMap = new ScalarColumnMap(discriminatorTypeUsage, columnName, 0, GetDiscriminatorOrdinalFromReader(storeDataReader, columnName, mapping.FunctionImport)); discriminatorColumns[i] = columnMap; } return discriminatorColumns; } /// /// Given a store datareader and a member of an edmType, find the column ordinal /// in the datareader with the name of the member. /// /// /// ///private static int GetMemberOrdinalFromReader(DbDataReader storeDataReader, EdmMember member) { int result; if (!TryGetColumnOrdinalFromReader(storeDataReader, member.Name, out result)) { throw EntityUtil.CommandExecutionDataReaderMissingColumnForType(member); } return result; } /// /// Given a store datareader, a column name, find the column ordinal /// in the datareader with the name of the column. /// /// We only have the functionImport provided to include it in the exception /// message. /// /// /// /// ///private static int GetDiscriminatorOrdinalFromReader(DbDataReader storeDataReader, string columnName, EdmFunction functionImport) { int result; if (!TryGetColumnOrdinalFromReader(storeDataReader, columnName, out result)) { throw EntityUtil.CommandExecutionDataReaderMissinDiscriminatorColumn(columnName, functionImport); } return result; } /// /// Given a store datareader and a column name, try to find the column ordinal /// in the datareader with the name of the column. /// /// /// /// ///true if found, false otherwise. private static bool TryGetColumnOrdinalFromReader(DbDataReader storeDataReader, string columnName, out int ordinal) { if (0 == storeDataReader.FieldCount) { // If there are no fields, there can't be a match (this check avoids // an InvalidOperationException on the call to GetOrdinal) ordinal = default(int); return false; } // Wrap ordinal lookup for the member so that we can throw a nice exception. try { ordinal = storeDataReader.GetOrdinal(columnName); return true; } catch (IndexOutOfRangeException) { // No column matching the column name found ordinal = default(int); return false; } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. //------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // // @owner [....], [....] //----------------------------------------------------------------------------- using System.Data.Common; using System.Data.Mapping; using System.Data.Metadata.Edm; using System.Diagnostics; using System.Collections.Generic; namespace System.Data.Query.InternalTrees { ////// Factory methods for prescriptive column map patterns (includes default /// column maps for -- soon to be -- public materializer services and function /// mappings). /// internal static class ColumnMapFactory { ////// Creates a column map for the given reader and function mapping. /// internal static CollectionColumnMap CreateFunctionImportEntityColumnMap(DbDataReader storeDataReader, FunctionImportMapping mapping, EntitySet entitySet, EntityType baseEntityType) { if (mapping.NormalizedEntityTypeMappings.Count == 0) // no explicit mapping; use default non-polymorphic reader { // if there is no mapping, create default mapping to root entity type Debug.Assert(!baseEntityType.Abstract, "mapping loader must verify abstract types have explicit mapping"); return CreateColumnMapFromReaderAndType(storeDataReader, baseEntityType, entitySet); } // Generate column maps for all discriminators ScalarColumnMap[] discriminatorColumns = CreateDiscriminatorColumnMaps(storeDataReader, mapping); // Generate default maps for all mapped entity types var mappedEntityTypes = new HashSet(mapping.MappedEntityTypes); mappedEntityTypes.Add(baseEntityType); // make sure the base type is represented Dictionary typeChoices = new Dictionary (mappedEntityTypes.Count); ColumnMap[] baseTypeColumnMaps = null; foreach (EntityType entityType in mappedEntityTypes) { ColumnMap[] propertyColumnMaps = GetColumnMapsForType(storeDataReader, entityType); EntityColumnMap entityColumnMap = CreateEntityTypeElementColumnMap(storeDataReader, entityType, entitySet, propertyColumnMaps); typeChoices.Add(entityType, entityColumnMap); if (entityType == baseEntityType) { baseTypeColumnMaps = propertyColumnMaps; } } // NOTE: We don't have a null sentinel here, because the stored proc won't // return one anyway; we'll just presume the data's always there. MultipleDiscriminatorPolymorphicColumnMap polymorphicMap = new MultipleDiscriminatorPolymorphicColumnMap(TypeUsage.Create(baseEntityType), baseEntityType.Name, baseTypeColumnMaps, discriminatorColumns, typeChoices, mapping.Discriminate); CollectionColumnMap collection = new SimpleCollectionColumnMap(baseEntityType.GetCollectionType().TypeUsage, baseEntityType.Name, polymorphicMap, null, null, null); return collection; } /// /// Build the collectionColumnMap from a store datareader, a type and an entitySet. /// /// /// /// ///private static CollectionColumnMap CreateColumnMapFromReaderAndType(DbDataReader storeDataReader, EdmType edmType, EntitySet entitySet) { if (!Helper.IsEntityType(edmType) && null != entitySet) { throw EntityUtil.EntitySetForNonEntityType(); } // Next, build the ColumnMap directly from the edmType and entitySet provided. ColumnMap[] propertyColumnMaps = GetColumnMapsForType(storeDataReader, edmType); ColumnMap elementColumnMap = null; // NOTE: We don't have a null sentinel here, because the stored proc won't // return one anyway; we'll just presume the data's always there. if (Helper.IsRowType(edmType)) { elementColumnMap = new RecordColumnMap(TypeUsage.Create(edmType), edmType.Name, propertyColumnMaps, null); } else if (Helper.IsComplexType(edmType)) { elementColumnMap = new ComplexTypeColumnMap(TypeUsage.Create(edmType), edmType.Name, propertyColumnMaps, null); } else if (Helper.IsPrimitiveType(edmType)) { if (storeDataReader.FieldCount != 1) { throw EntityUtil.CommandExecutionDataReaderFieldCountForPrimitiveType(); } elementColumnMap = new ScalarColumnMap(TypeUsage.Create(edmType), edmType.Name, 0, 0); } else if (Helper.IsEntityType(edmType)) { elementColumnMap = CreateEntityTypeElementColumnMap(storeDataReader, edmType, entitySet, propertyColumnMaps); } else { Debug.Assert(false, "unexpected edmType?"); } CollectionColumnMap collection = new SimpleCollectionColumnMap(edmType.GetCollectionType().TypeUsage, edmType.Name, elementColumnMap, null, null, null); return collection; } /// /// Build the entityColumnMap from a store datareader, a type and an entitySet and /// a list ofproperties. /// /// /// /// /// ///private static EntityColumnMap CreateEntityTypeElementColumnMap(DbDataReader storeDataReader, EdmType edmType, EntitySet entitySet, ColumnMap[] propertyColumnMaps) { // If the consumer didn't specify an entity set, we just dummy up // the no-entity-identity-entity-set. SimpleEntityIdentity simpleEntityIdentity = EntityIdentity.NoEntityIdentity; if (null != entitySet) { EntityType entityType = (EntityType)entitySet.ElementType; Debug.Assert(entityType.IsAssignableFrom(edmType), "edmType, entitySet.ElementType mismatch!"); // If they've requested an EntitySet, then we need to construct a // SimpleEntityIdentity for that EntitySet. The tricky part here is // that the KeyColumns list must point at the same ColumnMap(s) that // the properties list points to, so we build a quick array of // ColumnMap(s) that are indexed by their ordinal; then we can walk // the list of keyMembers, and find the ordinal in the reader, and // pick the same ColumnMap for it. // Build the ordinal -> ColumnMap index ColumnMap[] ordinalToColumnMap = new ColumnMap[storeDataReader.FieldCount]; foreach (ColumnMap propertyColumnMap in propertyColumnMaps) { int ordinal = ((ScalarColumnMap)propertyColumnMap).ColumnPos; ordinalToColumnMap[ordinal] = propertyColumnMap; } // Now build the list of KeyColumns; IList keyMembers = entityType.KeyMembers; SimpleColumnMap[] keyColumns = new SimpleColumnMap[keyMembers.Count]; int keyMemberIndex = 0; foreach (EdmMember keyMember in keyMembers) { int keyOrdinal = GetMemberOrdinalFromReader(storeDataReader, keyMember); Debug.Assert(keyOrdinal >= 0, "keyMember for entity is not found by name in the data reader?"); ColumnMap keyColumnMap = ordinalToColumnMap[keyOrdinal]; Debug.Assert(null != keyColumnMap, "keyMember for entity isn't in properties collection for the entity?"); keyColumns[keyMemberIndex] = (SimpleColumnMap)keyColumnMap; keyMemberIndex++; } // And finally, the SimpleEntityIdentity... simpleEntityIdentity = new SimpleEntityIdentity(entitySet, keyColumns); } EntityColumnMap result = new EntityColumnMap(TypeUsage.Create(edmType), edmType.Name, propertyColumnMaps, simpleEntityIdentity); return result; } /// /// For a given edmType, build an array of scalarColumnMaps that map to the columns /// in the store datareader provided. Note that we're hooking things up by name, not /// by ordinal position. /// /// /// ///private static ColumnMap[] GetColumnMapsForType(DbDataReader storeDataReader, EdmType edmType) { // First get the list of properties; NOTE: we need to hook up the column by name, // not by position. IBaseList members = TypeHelpers.GetAllStructuralMembers(edmType); ColumnMap[] propertyColumnMaps = new ColumnMap[members.Count]; int index = 0; foreach (EdmMember member in members) { Debug.Assert(Helper.IsPrimitiveType(member.TypeUsage.EdmType), "non-primitive type?"); int ordinal = GetMemberOrdinalFromReader(storeDataReader, member); propertyColumnMaps[index] = new ScalarColumnMap(member.TypeUsage, member.Name, 0, ordinal); index++; } return propertyColumnMaps; } private static ScalarColumnMap[] CreateDiscriminatorColumnMaps(DbDataReader storeDataReader, FunctionImportMapping mapping) { // choose an arbitrary type for discriminator columns -- the type is not // actually statically known EdmType discriminatorType = MetadataItem.EdmProviderManifest.GetPrimitiveType(PrimitiveTypeKind.String); TypeUsage discriminatorTypeUsage = TypeUsage.Create(discriminatorType); ScalarColumnMap[] discriminatorColumns = new ScalarColumnMap[mapping.DiscriminatorColumns.Count]; for (int i = 0; i < discriminatorColumns.Length; i++) { string columnName = mapping.DiscriminatorColumns[i]; ScalarColumnMap columnMap = new ScalarColumnMap(discriminatorTypeUsage, columnName, 0, GetDiscriminatorOrdinalFromReader(storeDataReader, columnName, mapping.FunctionImport)); discriminatorColumns[i] = columnMap; } return discriminatorColumns; } /// /// Given a store datareader and a member of an edmType, find the column ordinal /// in the datareader with the name of the member. /// /// /// ///private static int GetMemberOrdinalFromReader(DbDataReader storeDataReader, EdmMember member) { int result; if (!TryGetColumnOrdinalFromReader(storeDataReader, member.Name, out result)) { throw EntityUtil.CommandExecutionDataReaderMissingColumnForType(member); } return result; } /// /// Given a store datareader, a column name, find the column ordinal /// in the datareader with the name of the column. /// /// We only have the functionImport provided to include it in the exception /// message. /// /// /// /// ///private static int GetDiscriminatorOrdinalFromReader(DbDataReader storeDataReader, string columnName, EdmFunction functionImport) { int result; if (!TryGetColumnOrdinalFromReader(storeDataReader, columnName, out result)) { throw EntityUtil.CommandExecutionDataReaderMissinDiscriminatorColumn(columnName, functionImport); } return result; } /// /// Given a store datareader and a column name, try to find the column ordinal /// in the datareader with the name of the column. /// /// /// /// ///true if found, false otherwise. private static bool TryGetColumnOrdinalFromReader(DbDataReader storeDataReader, string columnName, out int ordinal) { if (0 == storeDataReader.FieldCount) { // If there are no fields, there can't be a match (this check avoids // an InvalidOperationException on the call to GetOrdinal) ordinal = default(int); return false; } // Wrap ordinal lookup for the member so that we can throw a nice exception. try { ordinal = storeDataReader.GetOrdinal(columnName); return true; } catch (IndexOutOfRangeException) { // No column matching the column name found ordinal = default(int); return false; } } } } // 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
- BatchStream.cs
- SqlCacheDependencyDatabase.cs
- ReflectionServiceProvider.cs
- RectangleGeometry.cs
- DropShadowEffect.cs
- Mappings.cs
- ThicknessKeyFrameCollection.cs
- CompilerCollection.cs
- VerificationAttribute.cs
- Brush.cs
- Menu.cs
- TextRangeSerialization.cs
- WhiteSpaceTrimStringConverter.cs
- GifBitmapDecoder.cs
- ThreadExceptionEvent.cs
- HtmlElementErrorEventArgs.cs
- propertytag.cs
- BulletedListDesigner.cs
- XDeferredAxisSource.cs
- XmlPropertyBag.cs
- TriState.cs
- XmlSchemaSimpleType.cs
- ComplexBindingPropertiesAttribute.cs
- FtpWebRequest.cs
- DPTypeDescriptorContext.cs
- SeparatorAutomationPeer.cs
- X509UI.cs
- KnownBoxes.cs
- MergablePropertyAttribute.cs
- BitmapEffectRenderDataResource.cs
- StylusOverProperty.cs
- SafeNativeMethodsMilCoreApi.cs
- TableProviderWrapper.cs
- RepeatInfo.cs
- XDRSchema.cs
- SelectionProcessor.cs
- SubpageParagraph.cs
- TabItemWrapperAutomationPeer.cs
- ITextView.cs
- InfoCardRSAPKCS1KeyExchangeFormatter.cs
- FamilyTypefaceCollection.cs
- Preprocessor.cs
- SafeBuffer.cs
- TimelineClockCollection.cs
- ReachSerializationUtils.cs
- IIS7WorkerRequest.cs
- MulticastDelegate.cs
- shaperfactoryquerycachekey.cs
- MouseDevice.cs
- CodeRegionDirective.cs
- CookielessData.cs
- CustomCategoryAttribute.cs
- ContentHostHelper.cs
- AddInPipelineAttributes.cs
- FormattedTextSymbols.cs
- PenLineJoinValidation.cs
- TraceListeners.cs
- AnimationStorage.cs
- SingleSelectRootGridEntry.cs
- RuntimeConfig.cs
- ApplicationFileParser.cs
- ObservableCollection.cs
- FixedTextView.cs
- SupportsEventValidationAttribute.cs
- SqlBooleanMismatchVisitor.cs
- ListViewCancelEventArgs.cs
- ParseChildrenAsPropertiesAttribute.cs
- SqlFunctionAttribute.cs
- OutputCacheModule.cs
- AmbientEnvironment.cs
- Vector3DCollection.cs
- autovalidator.cs
- RTTrackingProfile.cs
- Avt.cs
- TextServicesProperty.cs
- WindowsGraphicsCacheManager.cs
- GeometryCombineModeValidation.cs
- SupportsPreviewControlAttribute.cs
- AttachedPropertyDescriptor.cs
- CharUnicodeInfo.cs
- CachingHintValidation.cs
- GridViewUpdatedEventArgs.cs
- activationcontext.cs
- WebPartAuthorizationEventArgs.cs
- TypeExtensionConverter.cs
- TracingConnectionInitiator.cs
- Vector3DCollectionConverter.cs
- StorageEntitySetMapping.cs
- KeyedHashAlgorithm.cs
- DynamicValidatorEventArgs.cs
- TableItemProviderWrapper.cs
- BlockUIContainer.cs
- WebServiceClientProxyGenerator.cs
- __ConsoleStream.cs
- Vector3D.cs
- CodeTypeParameterCollection.cs
- XmlSchemaAnnotation.cs
- GeometryConverter.cs
- AmbientValueAttribute.cs
- TimeZone.cs