Code:
/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / Orcas / QFE / ndp / fx / src / DataEntity / System / Data / Map / Update / Internal / ViewLoader.cs / 2 / ViewLoader.cs
//---------------------------------------------------------------------- //// Copyright (c) Microsoft Corporation. All rights reserved. // // // @owner [....] // @backupOwner [....] //--------------------------------------------------------------------- using System.Data.Common.CommandTrees; using System.Data.Metadata.Edm; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Data.Common.CommandTrees.Internal; using System.Data.Common.Utils; using System.Diagnostics; using System.Data.Common; using System.Data.Objects; using System.Linq; using System.Threading; namespace System.Data.Mapping.Update.Internal { ////// Retrieves update mapping views and dependency information for update mapping views. Acts as a wrapper around /// the metadata workspace (and allows direct definition of update mapping views for test purposes). /// internal class ViewLoader { #region Constructors ////// Constructor specifying a metadata workspace to use for mapping views. /// /// mapping item collection used for retrieving updating mapping views. internal ViewLoader(StorageMappingItemCollection mappingItemCollection) { Debug.Assert(mappingItemCollection != null); m_mappingItemCollection = mappingItemCollection; } #endregion #region Fields private readonly Dictionarym_associationSetMetadata = new Dictionary (); private readonly Dictionary > m_affectedTables = new Dictionary >(); private readonly Set m_serverGenProperties = new Set (); private readonly Set m_isNullConditionProperties = new Set (); private readonly StorageMappingItemCollection m_mappingItemCollection; private readonly Dictionary m_functionMappingTranslators = new Dictionary ( EqualityComparer .Default); private readonly ReaderWriterLockSlim m_readerWriterLock = new ReaderWriterLockSlim(); #endregion #region Methods /// /// For a given extent, returns the function mapping translator. /// /// Association set or entity set for which to retrieve a translator ///Function translator or null if none exists for this extent internal FunctionMappingTranslator GetFunctionMappingTranslator(EntitySetBase extent) { return SyncGetValue(m_functionMappingTranslators, extent); } ////// Returns store tables affected by modifications to a particular C-layer extent. Although this /// information can be inferred from the update view, we want to avoid compiling or loading /// views when not required. This information can be directly determined from mapping metadata. /// /// C-layer extent. ///Affected store tables. internal SetGetAffectedTables(EntitySetBase extent) { return SyncGetValue(m_affectedTables, extent); } /// /// Gets information relevant to the processing of an AssociationSet in the update pipeline. /// Caches information on first retrieval. /// internal AssociationSetMetadata GetAssociationSetMetadata(AssociationSet associationSet) { return SyncGetValue(m_associationSetMetadata, associationSet); } ////// Determines whether the given member maps to a server-generated column in the store. /// Requires: InitializeExtentInformation has been called for the extent being persisted. /// /// Member to lookup ///Whether the member is server generated in some context internal bool IsServerGen(EdmMember member) { return SyncContains(m_serverGenProperties, member); } ////// Determines whether the given member maps to a column participating in an isnull /// condition. Useful to determine if a nullability constraint violation is going to /// cause roundtripping problems (e.g. if type is based on nullability of a 'non-nullable' /// property of a derived entity type) /// internal bool IsNullConditionMember(EdmMember member) { return SyncContains(m_isNullConditionProperties, member); } ////// Utility method reading value from dictionary within read lock. /// private T_Value SyncGetValue(Dictionary dictionary, T_Key key) { m_readerWriterLock.EnterReadLock(); try { return dictionary[key]; } finally { m_readerWriterLock.ExitReadLock(); } } /// /// Utility method checking for membership of element in set within read lock. /// private bool SyncContains(Set set, T_Element element) { m_readerWriterLock.EnterReadLock(); try { return set.Contains(element); } finally { m_readerWriterLock.ExitReadLock(); } } /// /// Initializes all information relevant to the entity set. /// /// Association set or entity set to load. /// metadata workspace internal void SyncInitializeEntitySet(EntitySetBase entitySetBase, MetadataWorkspace workspace) { m_readerWriterLock.EnterReadLock(); try { // check if we've already done the work for this entity set if (m_affectedTables.ContainsKey(entitySetBase)) { return; } } finally { m_readerWriterLock.ExitReadLock(); } // acquire a write lock m_readerWriterLock.EnterWriteLock(); try { // see if we've since done the work for this entity set if (m_affectedTables.ContainsKey(entitySetBase)) { return; } InitializeEntitySet(entitySetBase, workspace); } finally { m_readerWriterLock.ExitWriteLock(); } } private void InitializeEntitySet(EntitySetBase entitySetBase, MetadataWorkspace workspace) { // make sure views have been generated for this sub-graph (trigger generation of the sub-graph // by retrieving a view for one of its components; not actually using the view here) m_mappingItemCollection.GetGeneratedView(entitySetBase, workspace); SetaffectedTables = new Set (); StorageEntityContainerMapping mapping = (StorageEntityContainerMapping)m_mappingItemCollection.GetMap(entitySetBase.EntityContainer); if (null != mapping) { Set isNullConditionColumns = new Set (); // find extent in the container mapping StorageSetMapping setMapping; if (entitySetBase.BuiltInTypeKind == BuiltInTypeKind.EntitySet) { setMapping = mapping.GetEntitySetMapping(entitySetBase.Name); // Check for members that have result bindings in a function mapping. If a // function returns the member values, it indicates they are server-generated m_serverGenProperties.Unite(GetMembersWithResultBinding((StorageEntitySetMapping)setMapping)); } else if (entitySetBase.BuiltInTypeKind == BuiltInTypeKind.AssociationSet) { setMapping = mapping.GetRelationshipSetMapping(entitySetBase.Name); } else { Debug.Fail("unexpected extent type " + entitySetBase.BuiltInTypeKind); throw EntityUtil.NotSupported(); } // gather interesting tables, columns and properties from mapping fragments foreach (StorageMappingFragment mappingFragment in GetMappingFragments(setMapping)) { affectedTables.Add(mappingFragment.TableSet); // get all property mappings to figure out if anything is server generated m_serverGenProperties.AddRange(FindServerGenMembers(mappingFragment)); // get all columns participating in is null conditions isNullConditionColumns.AddRange(FindIsNullConditionColumns(mappingFragment)); } if (0 < isNullConditionColumns.Count) { // gather is null condition properties based on is null condition columns foreach (StorageMappingFragment mappingFragment in GetMappingFragments(setMapping)) { m_isNullConditionProperties.AddRange(FindPropertiesMappedToColumns(isNullConditionColumns, mappingFragment)); } } } m_affectedTables.Add(entitySetBase, affectedTables.MakeReadOnly()); InitializeFunctionMappingTranslators(entitySetBase, mapping); // for association sets, initialize AssociationSetMetadata if no function has claimed ownership // of the association yet if (entitySetBase.BuiltInTypeKind == BuiltInTypeKind.AssociationSet) { AssociationSet associationSet = (AssociationSet)entitySetBase; if (!m_associationSetMetadata.ContainsKey(associationSet)) { m_associationSetMetadata.Add(associationSet, new AssociationSetMetadata( m_affectedTables[associationSet], associationSet, workspace)); } } } /// /// Yields all members appearing in function mapping result bindings. /// /// Set mapping to examine ///All result bindings private IEnumerableGetMembersWithResultBinding(StorageEntitySetMapping entitySetMapping) { foreach (StorageEntityTypeFunctionMapping typeFunctionMapping in entitySetMapping.FunctionMappings) { // look at all result bindings for insert and update commands if (null != typeFunctionMapping.InsertFunctionMapping.ResultBindings) { foreach (StorageFunctionResultBinding binding in typeFunctionMapping.InsertFunctionMapping.ResultBindings) { yield return binding.Property; } } if (null != typeFunctionMapping.UpdateFunctionMapping.ResultBindings) { foreach (StorageFunctionResultBinding binding in typeFunctionMapping.UpdateFunctionMapping.ResultBindings) { yield return binding.Property; } } } } // Loads and registers any function mapping translators for the given extent (and related container) private void InitializeFunctionMappingTranslators(EntitySetBase entitySetBase, StorageEntityContainerMapping mapping) { KeyToListMap requiredEnds = new KeyToListMap ( EqualityComparer .Default); // see if function mapping metadata needs to be processed if (!m_functionMappingTranslators.ContainsKey(entitySetBase)) { // load all function mapping data from the current entity container foreach (StorageEntitySetMapping entitySetMapping in mapping.EntitySetMaps) { if (0 < entitySetMapping.FunctionMappings.Count) { // register the function mapping m_functionMappingTranslators.Add(entitySetMapping.Set, FunctionMappingTranslator.CreateEntitySetFunctionMappingTranslator(entitySetMapping)); // register "null" function translators for all implicitly mapped association sets foreach (AssociationSetEnd end in entitySetMapping.ImplicitlyMappedAssociationSetEnds) { AssociationSet associationSet = end.ParentAssociationSet; if (!m_functionMappingTranslators.ContainsKey(associationSet)) { m_functionMappingTranslators.Add(associationSet, FunctionMappingTranslator.CreateAssociationSetFunctionMappingTranslator(null)); } // Remember that the current entity set is required for all updates to the collocated // relationship set. This entity set's end is opposite the target end for the mapping. AssociationSetEnd oppositeEnd = MetadataHelper.GetOppositeEnd(end); requiredEnds.Add(associationSet, oppositeEnd.CorrespondingAssociationEndMember); } } else { // register null translator (so that we never attempt to process this extent again) m_functionMappingTranslators.Add(entitySetMapping.Set, null); } } foreach (StorageAssociationSetMapping associationSetMapping in mapping.RelationshipSetMaps) { if (null != associationSetMapping.FunctionMapping) { AssociationSet set = (AssociationSet)associationSetMapping.Set; // use indexer rather than Add since the association set may already have an implicit function // mapping -- this explicit function mapping takes precedence in such cases m_functionMappingTranslators.Add(set, FunctionMappingTranslator.CreateAssociationSetFunctionMappingTranslator(associationSetMapping)); // remember that we've seen a function mapping for this association set, which overrides // any other behaviors for determining required/optional ends requiredEnds.AddRange(set, Enumerable.Empty ()); } else { if (!m_functionMappingTranslators.ContainsKey(associationSetMapping.Set)) { // register null translator (so that we never attempt to process this extent again) m_functionMappingTranslators.Add(associationSetMapping.Set, null); } } } } // register association metadata for all association sets encountered foreach (AssociationSet associationSet in requiredEnds.Keys) { m_associationSetMetadata.Add(associationSet, new AssociationSetMetadata( requiredEnds.EnumerateValues(associationSet))); } } /// /// Gets all model properties mapped to server generated columns. /// private static IEnumerableFindServerGenMembers(StorageMappingFragment mappingFragment) { foreach (var scalarPropertyMapping in FlattenPropertyMappings(mappingFragment.AllProperties) .OfType ()) { if (StoreGeneratedPattern.None != MetadataHelper.GetStoreGeneratedPattern(scalarPropertyMapping.ColumnProperty)) { yield return scalarPropertyMapping.EdmProperty; } } } /// /// Gets all store columns participating in is null conditions. /// private static IEnumerableFindIsNullConditionColumns(StorageMappingFragment mappingFragment) { foreach (var conditionPropertyMapping in FlattenPropertyMappings(mappingFragment.AllProperties) .OfType ()) { if (conditionPropertyMapping.ColumnProperty != null && conditionPropertyMapping.IsNull.HasValue) { yield return conditionPropertyMapping.ColumnProperty; } } } /// /// Gets all model properties mapped to given columns. /// private static IEnumerableFindPropertiesMappedToColumns(Set columns, StorageMappingFragment mappingFragment) { foreach (var scalarPropertyMapping in FlattenPropertyMappings(mappingFragment.AllProperties) .OfType ()) { if (columns.Contains(scalarPropertyMapping.ColumnProperty)) { yield return scalarPropertyMapping.EdmProperty; } } } /// /// Enumerates all mapping fragments in given set mapping. /// private static IEnumerableGetMappingFragments(StorageSetMapping setMapping) { // get all type mappings for the extent foreach (StorageTypeMapping typeMapping in setMapping.TypeMappings) { // get all table mapping fragments for the type foreach (StorageMappingFragment mappingFragment in typeMapping.MappingFragments) { yield return mappingFragment; } } } /// /// Returns all bottom-level mappings (e.g. conditions and scalar property mappings but not complex property mappings /// whose components are returned) /// private static IEnumerableFlattenPropertyMappings(System.Collections.ObjectModel.ReadOnlyCollection propertyMappings) { foreach (StoragePropertyMapping propertyMapping in propertyMappings) { StorageComplexPropertyMapping complexPropertyMapping = propertyMapping as StorageComplexPropertyMapping; if (null != complexPropertyMapping) { foreach (StorageComplexTypeMapping complexTypeMapping in complexPropertyMapping.TypeMappings) { // recursively call self with nested type foreach (StoragePropertyMapping nestedPropertyMapping in FlattenPropertyMappings(complexTypeMapping.AllProperties)) { yield return nestedPropertyMapping; } } } else { yield return propertyMapping; } } } #endregion } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. //---------------------------------------------------------------------- // // Copyright (c) Microsoft Corporation. All rights reserved. // // // @owner [....] // @backupOwner [....] //--------------------------------------------------------------------- using System.Data.Common.CommandTrees; using System.Data.Metadata.Edm; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Data.Common.CommandTrees.Internal; using System.Data.Common.Utils; using System.Diagnostics; using System.Data.Common; using System.Data.Objects; using System.Linq; using System.Threading; namespace System.Data.Mapping.Update.Internal { ////// Retrieves update mapping views and dependency information for update mapping views. Acts as a wrapper around /// the metadata workspace (and allows direct definition of update mapping views for test purposes). /// internal class ViewLoader { #region Constructors ////// Constructor specifying a metadata workspace to use for mapping views. /// /// mapping item collection used for retrieving updating mapping views. internal ViewLoader(StorageMappingItemCollection mappingItemCollection) { Debug.Assert(mappingItemCollection != null); m_mappingItemCollection = mappingItemCollection; } #endregion #region Fields private readonly Dictionarym_associationSetMetadata = new Dictionary (); private readonly Dictionary > m_affectedTables = new Dictionary >(); private readonly Set m_serverGenProperties = new Set (); private readonly Set m_isNullConditionProperties = new Set (); private readonly StorageMappingItemCollection m_mappingItemCollection; private readonly Dictionary m_functionMappingTranslators = new Dictionary ( EqualityComparer .Default); private readonly ReaderWriterLockSlim m_readerWriterLock = new ReaderWriterLockSlim(); #endregion #region Methods /// /// For a given extent, returns the function mapping translator. /// /// Association set or entity set for which to retrieve a translator ///Function translator or null if none exists for this extent internal FunctionMappingTranslator GetFunctionMappingTranslator(EntitySetBase extent) { return SyncGetValue(m_functionMappingTranslators, extent); } ////// Returns store tables affected by modifications to a particular C-layer extent. Although this /// information can be inferred from the update view, we want to avoid compiling or loading /// views when not required. This information can be directly determined from mapping metadata. /// /// C-layer extent. ///Affected store tables. internal SetGetAffectedTables(EntitySetBase extent) { return SyncGetValue(m_affectedTables, extent); } /// /// Gets information relevant to the processing of an AssociationSet in the update pipeline. /// Caches information on first retrieval. /// internal AssociationSetMetadata GetAssociationSetMetadata(AssociationSet associationSet) { return SyncGetValue(m_associationSetMetadata, associationSet); } ////// Determines whether the given member maps to a server-generated column in the store. /// Requires: InitializeExtentInformation has been called for the extent being persisted. /// /// Member to lookup ///Whether the member is server generated in some context internal bool IsServerGen(EdmMember member) { return SyncContains(m_serverGenProperties, member); } ////// Determines whether the given member maps to a column participating in an isnull /// condition. Useful to determine if a nullability constraint violation is going to /// cause roundtripping problems (e.g. if type is based on nullability of a 'non-nullable' /// property of a derived entity type) /// internal bool IsNullConditionMember(EdmMember member) { return SyncContains(m_isNullConditionProperties, member); } ////// Utility method reading value from dictionary within read lock. /// private T_Value SyncGetValue(Dictionary dictionary, T_Key key) { m_readerWriterLock.EnterReadLock(); try { return dictionary[key]; } finally { m_readerWriterLock.ExitReadLock(); } } /// /// Utility method checking for membership of element in set within read lock. /// private bool SyncContains(Set set, T_Element element) { m_readerWriterLock.EnterReadLock(); try { return set.Contains(element); } finally { m_readerWriterLock.ExitReadLock(); } } /// /// Initializes all information relevant to the entity set. /// /// Association set or entity set to load. /// metadata workspace internal void SyncInitializeEntitySet(EntitySetBase entitySetBase, MetadataWorkspace workspace) { m_readerWriterLock.EnterReadLock(); try { // check if we've already done the work for this entity set if (m_affectedTables.ContainsKey(entitySetBase)) { return; } } finally { m_readerWriterLock.ExitReadLock(); } // acquire a write lock m_readerWriterLock.EnterWriteLock(); try { // see if we've since done the work for this entity set if (m_affectedTables.ContainsKey(entitySetBase)) { return; } InitializeEntitySet(entitySetBase, workspace); } finally { m_readerWriterLock.ExitWriteLock(); } } private void InitializeEntitySet(EntitySetBase entitySetBase, MetadataWorkspace workspace) { // make sure views have been generated for this sub-graph (trigger generation of the sub-graph // by retrieving a view for one of its components; not actually using the view here) m_mappingItemCollection.GetGeneratedView(entitySetBase, workspace); SetaffectedTables = new Set (); StorageEntityContainerMapping mapping = (StorageEntityContainerMapping)m_mappingItemCollection.GetMap(entitySetBase.EntityContainer); if (null != mapping) { Set isNullConditionColumns = new Set (); // find extent in the container mapping StorageSetMapping setMapping; if (entitySetBase.BuiltInTypeKind == BuiltInTypeKind.EntitySet) { setMapping = mapping.GetEntitySetMapping(entitySetBase.Name); // Check for members that have result bindings in a function mapping. If a // function returns the member values, it indicates they are server-generated m_serverGenProperties.Unite(GetMembersWithResultBinding((StorageEntitySetMapping)setMapping)); } else if (entitySetBase.BuiltInTypeKind == BuiltInTypeKind.AssociationSet) { setMapping = mapping.GetRelationshipSetMapping(entitySetBase.Name); } else { Debug.Fail("unexpected extent type " + entitySetBase.BuiltInTypeKind); throw EntityUtil.NotSupported(); } // gather interesting tables, columns and properties from mapping fragments foreach (StorageMappingFragment mappingFragment in GetMappingFragments(setMapping)) { affectedTables.Add(mappingFragment.TableSet); // get all property mappings to figure out if anything is server generated m_serverGenProperties.AddRange(FindServerGenMembers(mappingFragment)); // get all columns participating in is null conditions isNullConditionColumns.AddRange(FindIsNullConditionColumns(mappingFragment)); } if (0 < isNullConditionColumns.Count) { // gather is null condition properties based on is null condition columns foreach (StorageMappingFragment mappingFragment in GetMappingFragments(setMapping)) { m_isNullConditionProperties.AddRange(FindPropertiesMappedToColumns(isNullConditionColumns, mappingFragment)); } } } m_affectedTables.Add(entitySetBase, affectedTables.MakeReadOnly()); InitializeFunctionMappingTranslators(entitySetBase, mapping); // for association sets, initialize AssociationSetMetadata if no function has claimed ownership // of the association yet if (entitySetBase.BuiltInTypeKind == BuiltInTypeKind.AssociationSet) { AssociationSet associationSet = (AssociationSet)entitySetBase; if (!m_associationSetMetadata.ContainsKey(associationSet)) { m_associationSetMetadata.Add(associationSet, new AssociationSetMetadata( m_affectedTables[associationSet], associationSet, workspace)); } } } /// /// Yields all members appearing in function mapping result bindings. /// /// Set mapping to examine ///All result bindings private IEnumerableGetMembersWithResultBinding(StorageEntitySetMapping entitySetMapping) { foreach (StorageEntityTypeFunctionMapping typeFunctionMapping in entitySetMapping.FunctionMappings) { // look at all result bindings for insert and update commands if (null != typeFunctionMapping.InsertFunctionMapping.ResultBindings) { foreach (StorageFunctionResultBinding binding in typeFunctionMapping.InsertFunctionMapping.ResultBindings) { yield return binding.Property; } } if (null != typeFunctionMapping.UpdateFunctionMapping.ResultBindings) { foreach (StorageFunctionResultBinding binding in typeFunctionMapping.UpdateFunctionMapping.ResultBindings) { yield return binding.Property; } } } } // Loads and registers any function mapping translators for the given extent (and related container) private void InitializeFunctionMappingTranslators(EntitySetBase entitySetBase, StorageEntityContainerMapping mapping) { KeyToListMap requiredEnds = new KeyToListMap ( EqualityComparer .Default); // see if function mapping metadata needs to be processed if (!m_functionMappingTranslators.ContainsKey(entitySetBase)) { // load all function mapping data from the current entity container foreach (StorageEntitySetMapping entitySetMapping in mapping.EntitySetMaps) { if (0 < entitySetMapping.FunctionMappings.Count) { // register the function mapping m_functionMappingTranslators.Add(entitySetMapping.Set, FunctionMappingTranslator.CreateEntitySetFunctionMappingTranslator(entitySetMapping)); // register "null" function translators for all implicitly mapped association sets foreach (AssociationSetEnd end in entitySetMapping.ImplicitlyMappedAssociationSetEnds) { AssociationSet associationSet = end.ParentAssociationSet; if (!m_functionMappingTranslators.ContainsKey(associationSet)) { m_functionMappingTranslators.Add(associationSet, FunctionMappingTranslator.CreateAssociationSetFunctionMappingTranslator(null)); } // Remember that the current entity set is required for all updates to the collocated // relationship set. This entity set's end is opposite the target end for the mapping. AssociationSetEnd oppositeEnd = MetadataHelper.GetOppositeEnd(end); requiredEnds.Add(associationSet, oppositeEnd.CorrespondingAssociationEndMember); } } else { // register null translator (so that we never attempt to process this extent again) m_functionMappingTranslators.Add(entitySetMapping.Set, null); } } foreach (StorageAssociationSetMapping associationSetMapping in mapping.RelationshipSetMaps) { if (null != associationSetMapping.FunctionMapping) { AssociationSet set = (AssociationSet)associationSetMapping.Set; // use indexer rather than Add since the association set may already have an implicit function // mapping -- this explicit function mapping takes precedence in such cases m_functionMappingTranslators.Add(set, FunctionMappingTranslator.CreateAssociationSetFunctionMappingTranslator(associationSetMapping)); // remember that we've seen a function mapping for this association set, which overrides // any other behaviors for determining required/optional ends requiredEnds.AddRange(set, Enumerable.Empty ()); } else { if (!m_functionMappingTranslators.ContainsKey(associationSetMapping.Set)) { // register null translator (so that we never attempt to process this extent again) m_functionMappingTranslators.Add(associationSetMapping.Set, null); } } } } // register association metadata for all association sets encountered foreach (AssociationSet associationSet in requiredEnds.Keys) { m_associationSetMetadata.Add(associationSet, new AssociationSetMetadata( requiredEnds.EnumerateValues(associationSet))); } } /// /// Gets all model properties mapped to server generated columns. /// private static IEnumerableFindServerGenMembers(StorageMappingFragment mappingFragment) { foreach (var scalarPropertyMapping in FlattenPropertyMappings(mappingFragment.AllProperties) .OfType ()) { if (StoreGeneratedPattern.None != MetadataHelper.GetStoreGeneratedPattern(scalarPropertyMapping.ColumnProperty)) { yield return scalarPropertyMapping.EdmProperty; } } } /// /// Gets all store columns participating in is null conditions. /// private static IEnumerableFindIsNullConditionColumns(StorageMappingFragment mappingFragment) { foreach (var conditionPropertyMapping in FlattenPropertyMappings(mappingFragment.AllProperties) .OfType ()) { if (conditionPropertyMapping.ColumnProperty != null && conditionPropertyMapping.IsNull.HasValue) { yield return conditionPropertyMapping.ColumnProperty; } } } /// /// Gets all model properties mapped to given columns. /// private static IEnumerableFindPropertiesMappedToColumns(Set columns, StorageMappingFragment mappingFragment) { foreach (var scalarPropertyMapping in FlattenPropertyMappings(mappingFragment.AllProperties) .OfType ()) { if (columns.Contains(scalarPropertyMapping.ColumnProperty)) { yield return scalarPropertyMapping.EdmProperty; } } } /// /// Enumerates all mapping fragments in given set mapping. /// private static IEnumerableGetMappingFragments(StorageSetMapping setMapping) { // get all type mappings for the extent foreach (StorageTypeMapping typeMapping in setMapping.TypeMappings) { // get all table mapping fragments for the type foreach (StorageMappingFragment mappingFragment in typeMapping.MappingFragments) { yield return mappingFragment; } } } /// /// Returns all bottom-level mappings (e.g. conditions and scalar property mappings but not complex property mappings /// whose components are returned) /// private static IEnumerableFlattenPropertyMappings(System.Collections.ObjectModel.ReadOnlyCollection propertyMappings) { foreach (StoragePropertyMapping propertyMapping in propertyMappings) { StorageComplexPropertyMapping complexPropertyMapping = propertyMapping as StorageComplexPropertyMapping; if (null != complexPropertyMapping) { foreach (StorageComplexTypeMapping complexTypeMapping in complexPropertyMapping.TypeMappings) { // recursively call self with nested type foreach (StoragePropertyMapping nestedPropertyMapping in FlattenPropertyMappings(complexTypeMapping.AllProperties)) { yield return nestedPropertyMapping; } } } else { yield return propertyMapping; } } } #endregion } } // 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
- ValidationEventArgs.cs
- SoapCodeExporter.cs
- ConfigurationStrings.cs
- RegexCharClass.cs
- DataGridViewCellFormattingEventArgs.cs
- InvalidOleVariantTypeException.cs
- Tokenizer.cs
- OdbcRowUpdatingEvent.cs
- WSSecureConversationDec2005.cs
- StylusSystemGestureEventArgs.cs
- GroupBoxRenderer.cs
- AutoGeneratedField.cs
- Variant.cs
- ForwardPositionQuery.cs
- HTMLTextWriter.cs
- CheckBoxField.cs
- ProgressBar.cs
- Directory.cs
- TableRowCollection.cs
- ValidatingCollection.cs
- Preprocessor.cs
- SystemIdentity.cs
- EffectiveValueEntry.cs
- ClientTarget.cs
- ByteFacetDescriptionElement.cs
- ReliabilityContractAttribute.cs
- MimeParameter.cs
- ControlTemplate.cs
- BamlLocalizer.cs
- MachineKeyConverter.cs
- SerializationException.cs
- HandlerWithFactory.cs
- DoubleAnimation.cs
- basemetadatamappingvisitor.cs
- TreeNode.cs
- Int32RectValueSerializer.cs
- RectangleConverter.cs
- PropertyGrid.cs
- NoResizeHandleGlyph.cs
- SqlRecordBuffer.cs
- GPRECTF.cs
- TransformValueSerializer.cs
- EventProviderWriter.cs
- SoapSchemaExporter.cs
- EntityViewGenerator.cs
- SettingsBindableAttribute.cs
- MinMaxParagraphWidth.cs
- FormViewPagerRow.cs
- linebase.cs
- DataGridState.cs
- HtmlInputSubmit.cs
- RightsManagementEncryptedStream.cs
- HtmlShim.cs
- QueryStringParameter.cs
- TimeEnumHelper.cs
- DataGridViewRowStateChangedEventArgs.cs
- NavigationHelper.cs
- SafeHandle.cs
- FixedSOMLineCollection.cs
- DictionaryTraceRecord.cs
- ProxyAttribute.cs
- PathSegmentCollection.cs
- XmlElementList.cs
- WinEventWrap.cs
- AppDomainManager.cs
- VersionUtil.cs
- DrawItemEvent.cs
- WebBrowserProgressChangedEventHandler.cs
- InternalPermissions.cs
- StylusDevice.cs
- QilInvoke.cs
- SpellerHighlightLayer.cs
- VerificationAttribute.cs
- HttpConfigurationContext.cs
- WeakReadOnlyCollection.cs
- DBAsyncResult.cs
- NativeMethods.cs
- NameValueConfigurationElement.cs
- UserControl.cs
- TemplateComponentConnector.cs
- DocumentApplication.cs
- ColumnClickEvent.cs
- CharEntityEncoderFallback.cs
- SmiContextFactory.cs
- ServiceParser.cs
- Convert.cs
- FontEmbeddingManager.cs
- CrossAppDomainChannel.cs
- QueueProcessor.cs
- SemanticBasicElement.cs
- DodSequenceMerge.cs
- LifetimeServices.cs
- CodeTypeReference.cs
- SecurityHelper.cs
- DataBoundControlHelper.cs
- Certificate.cs
- UrlPath.cs
- ColumnResizeAdorner.cs
- HashRepartitionEnumerator.cs
- TiffBitmapEncoder.cs