Code:
/ Dotnetfx_Win7_3.5.1 / Dotnetfx_Win7_3.5.1 / 3.5.1 / DEVDIV / depot / DevDiv / releases / Orcas / NetFXw7 / ndp / fx / src / DataEntity / System / Data / Map / Update / Internal / FunctionMappingTranslator.cs / 1 / FunctionMappingTranslator.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.Data.Entity; namespace System.Data.Mapping.Update.Internal { ////// Function mapping translators are defined per extent (entity set /// or association set) and manage the creation of function commands. /// internal abstract class FunctionMappingTranslator { ////// Requires: this translator must be registered to handle the entity set /// for the given state entry. /// /// Translates the given state entry to a command. /// /// Parent update translator (global state for the workload) /// State entry to translate. Must belong to the /// entity/association set handled by this translator ///Command corresponding to the given state entry internal abstract FunctionUpdateCommand Translate( UpdateTranslator translator, ExtractedStateEntry stateEntry); ////// Initialize a translator for the given entity set mapping. /// /// Entity set mapping. ///Translator. internal static FunctionMappingTranslator CreateEntitySetFunctionMappingTranslator( StorageEntitySetMapping setMapping) { return new EntitySetFunctionMappingTranslator(setMapping); } ////// Initialize a translator for the given association set mapping. /// /// Association set mapping. ///Translator. internal static FunctionMappingTranslator CreateAssociationSetFunctionMappingTranslator( StorageAssociationSetMapping setMapping) { return new AssociationSetFunctionMappingTranslator(setMapping); } private sealed class EntitySetFunctionMappingTranslator : FunctionMappingTranslator { private readonly Dictionarym_typeMappings; internal EntitySetFunctionMappingTranslator(StorageEntitySetMapping setMapping) { Debug.Assert(null != setMapping && null != setMapping.FunctionMappings && 0 < setMapping.FunctionMappings.Count, "set mapping must exist and must specify function mappings"); m_typeMappings = new Dictionary (); foreach (StorageEntityTypeFunctionMapping typeMapping in setMapping.FunctionMappings) { m_typeMappings.Add(typeMapping.EntityType, typeMapping); } } internal override FunctionUpdateCommand Translate( UpdateTranslator translator, ExtractedStateEntry stateEntry) { StorageFunctionMapping functionMapping = GetFunctionMapping(stateEntry); // create function object FunctionUpdateCommand command = new FunctionUpdateCommand(functionMapping, translator, stateEntry.Source); // bind all function parameters BindFunctionParameters(translator, stateEntry.Source, stateEntry.Original, stateEntry.Current, functionMapping, command); // interpret all result bindings if (null != functionMapping.ResultBindings) { foreach (StorageFunctionResultBinding resultBinding in functionMapping.ResultBindings) { PropagatorResult result = stateEntry.Current.GetMemberValue(resultBinding.Property); command.AddResultColumn(translator, resultBinding.ColumnName, result); } } return command; } private StorageFunctionMapping GetFunctionMapping(ExtractedStateEntry stateEntry) { // choose mapping based on type and operation StorageFunctionMapping functionMapping; EntityType entityType; if (null != stateEntry.Current) { entityType = (EntityType)stateEntry.Current.StructuralType; } else { entityType = (EntityType)stateEntry.Original.StructuralType; } switch (stateEntry.State) { case EntityState.Added: functionMapping = m_typeMappings[entityType].InsertFunctionMapping; break; case EntityState.Deleted: functionMapping = m_typeMappings[entityType].DeleteFunctionMapping; break; case EntityState.Unchanged: case EntityState.Modified: functionMapping = m_typeMappings[entityType].UpdateFunctionMapping; break; default: functionMapping = null; Debug.Fail("unexpected state"); break; } return functionMapping; } // Walks through all parameter bindings in the function mapping and binds the parameters to the // requested properties of the given state entry. private static void BindFunctionParameters(UpdateTranslator translator, IEntityStateEntry stateEntry, PropagatorResult original, PropagatorResult current, StorageFunctionMapping functionMapping, FunctionUpdateCommand command) { // bind all parameters EntityKey entityKey = stateEntry.EntityKey; foreach (StorageFunctionParameterBinding parameterBinding in functionMapping.ParameterBindings) { PropagatorResult result; // extract value if (null != parameterBinding.MemberPath.AssociationSetEnd) { result = RetrieveNavigationResult(translator, command, entityKey, parameterBinding); } else { // walk through the member path to find the appropriate propagator results result = parameterBinding.IsCurrent ? current : original; for (int i = parameterBinding.MemberPath.Members.Count; i > 0;) { --i; EdmMember member = parameterBinding.MemberPath.Members[i]; result = result.GetMemberValue(member); } } // create DbParameter command.SetParameterValue(result, parameterBinding, translator); } // Add rows affected parameter command.RegisterRowsAffectedParameter(functionMapping.RowsAffectedParameter); } // Retrieves the value of a function parameter binding to a relationship navigation value private static PropagatorResult RetrieveNavigationResult(UpdateTranslator translator, FunctionUpdateCommand command, EntityKey entityKey, StorageFunctionParameterBinding parameterBinding) { // Retrieve information about the navigation Debug.Assert(null != parameterBinding.MemberPath.AssociationSetEnd); AssociationSetEnd associationSetEnd = parameterBinding.MemberPath.AssociationSetEnd; AssociationSet associationSet = associationSetEnd.ParentAssociationSet; Debug.Assert(2 == parameterBinding.MemberPath.Members.Count, "association navigation member path " + "must consist of (exactly) one key property and one end member"); EdmProperty keyProperty = (EdmProperty)parameterBinding.MemberPath.Members[0]; AssociationEndMember endMember = parameterBinding.MemberPath.AssociationSetEnd.CorrespondingAssociationEndMember; // Find the relationship entry corresponding to the navigation IEntityStateEntry relationshipEntry = RetrieveNavigationStateEntry(translator, command, entityKey, associationSet, endMember, parameterBinding.IsCurrent); if (null == relationshipEntry) { // if no relationship entry was found, make sure it isn't required if (endMember.RelationshipMultiplicity == RelationshipMultiplicity.One) { string entitySetName = entityKey.EntitySetName; string associationSetName = associationSet.Name; throw EntityUtil.Update(Strings.Update_MissingRequiredRelationshipValue(entitySetName, associationSetName), null, command.GetStateEntries(translator)); } else { // return NULL value return PropagatorResult.CreateSimpleValue(PropagatorFlags.NoFlags, null); } } else { // remember that this entry is "in scope" for the relationship command.RegisterStateEntry(relationshipEntry); // get the actual value PropagatorResult relationshipResult = parameterBinding.IsCurrent ? translator.RecordConverter.ConvertCurrentValuesToPropagatorResult(relationshipEntry, null) : translator.RecordConverter.ConvertOriginalValuesToPropagatorResult(relationshipEntry, null); PropagatorResult endResult = relationshipResult.GetMemberValue(endMember); PropagatorResult keyResult = endResult.GetMemberValue(keyProperty); return keyResult; } } // Tries to find a state entry correspdonding to the given navigation, where "entityKey" is // the key of the parent. private static IEntityStateEntry RetrieveNavigationStateEntry(UpdateTranslator translator, FunctionUpdateCommand command, EntityKey entityKey, AssociationSet associationSetNavigation, AssociationEndMember endMember, bool isCurrent) { IEntityStateEntry relationshipEntry = null; foreach (IEntityStateEntry candidateEntry in translator.GetRelationships(entityKey)) { // check if this is the correct relationship entry if (candidateEntry.EntitySet.EdmEquals(associationSetNavigation)) { // get record containing values DbDataRecord record; if (isCurrent) { if (EntityState.Added == candidateEntry.State || EntityState.Unchanged == candidateEntry.State) { record = candidateEntry.CurrentValues; } else { // wrong version of the relationship continue; } } else { if (EntityState.Deleted == candidateEntry.State || EntityState.Unchanged == candidateEntry.State) { record = candidateEntry.OriginalValues; } else { // wrong version of the relationship continue; } } // find the end corresponding to the 'to' end int toOrdinal = record.GetOrdinal(endMember.Name); Debug.Assert(-1 != toOrdinal, "to end of relationship doesn't exist in record"); // the 'from' end must be the other end int fromOrdinal = 0 == toOrdinal ? 1 : 0; EntityKey fromKey = (EntityKey)record[fromOrdinal]; EntityKey toKey = (EntityKey)record[toOrdinal]; // check we're dealing with the correct relationship direction by looking at the from key if (fromKey == entityKey) { // we've found our match relationshipEntry = candidateEntry; break; } } } return relationshipEntry; } } private sealed class AssociationSetFunctionMappingTranslator : FunctionMappingTranslator { // If this value is null, it indicates that the association set is // only implicitly mapped as part of an entity set private readonly StorageAssociationSetFunctionMapping m_mapping; internal AssociationSetFunctionMappingTranslator(StorageAssociationSetMapping setMapping) { if (null != setMapping) { m_mapping = setMapping.FunctionMapping; } } internal override FunctionUpdateCommand Translate( UpdateTranslator translator, ExtractedStateEntry stateEntry) { if (null == m_mapping) { return null; } bool isInsert = EntityState.Added == stateEntry.State; // initialize a new command StorageFunctionMapping functionMapping = isInsert ? m_mapping.InsertFunctionMapping : m_mapping.DeleteFunctionMapping; FunctionUpdateCommand command = new FunctionUpdateCommand(functionMapping, translator, stateEntry.Source); // extract the relationship values from the state entry PropagatorResult recordResult; if (isInsert) { recordResult = stateEntry.Current; } else { recordResult = stateEntry.Original; } // bind parameters foreach (StorageFunctionParameterBinding parameterBinding in functionMapping.ParameterBindings) { // extract the relationship information Debug.Assert(2 == parameterBinding.MemberPath.Members.Count, "relationship parameter binding member " + "path should include the relationship end and key property only"); EdmProperty keyProperty = (EdmProperty)parameterBinding.MemberPath.Members[0]; AssociationEndMember endMember = (AssociationEndMember)parameterBinding.MemberPath.Members[1]; // get the end member PropagatorResult endResult = recordResult.GetMemberValue(endMember); PropagatorResult keyResult = endResult.GetMemberValue(keyProperty); command.SetParameterValue(keyResult, parameterBinding, translator); } // add rows affected output parameter command.RegisterRowsAffectedParameter(functionMapping.RowsAffectedParameter); return command; } } } } // 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.Data.Entity; namespace System.Data.Mapping.Update.Internal { ////// Function mapping translators are defined per extent (entity set /// or association set) and manage the creation of function commands. /// internal abstract class FunctionMappingTranslator { ////// Requires: this translator must be registered to handle the entity set /// for the given state entry. /// /// Translates the given state entry to a command. /// /// Parent update translator (global state for the workload) /// State entry to translate. Must belong to the /// entity/association set handled by this translator ///Command corresponding to the given state entry internal abstract FunctionUpdateCommand Translate( UpdateTranslator translator, ExtractedStateEntry stateEntry); ////// Initialize a translator for the given entity set mapping. /// /// Entity set mapping. ///Translator. internal static FunctionMappingTranslator CreateEntitySetFunctionMappingTranslator( StorageEntitySetMapping setMapping) { return new EntitySetFunctionMappingTranslator(setMapping); } ////// Initialize a translator for the given association set mapping. /// /// Association set mapping. ///Translator. internal static FunctionMappingTranslator CreateAssociationSetFunctionMappingTranslator( StorageAssociationSetMapping setMapping) { return new AssociationSetFunctionMappingTranslator(setMapping); } private sealed class EntitySetFunctionMappingTranslator : FunctionMappingTranslator { private readonly Dictionarym_typeMappings; internal EntitySetFunctionMappingTranslator(StorageEntitySetMapping setMapping) { Debug.Assert(null != setMapping && null != setMapping.FunctionMappings && 0 < setMapping.FunctionMappings.Count, "set mapping must exist and must specify function mappings"); m_typeMappings = new Dictionary (); foreach (StorageEntityTypeFunctionMapping typeMapping in setMapping.FunctionMappings) { m_typeMappings.Add(typeMapping.EntityType, typeMapping); } } internal override FunctionUpdateCommand Translate( UpdateTranslator translator, ExtractedStateEntry stateEntry) { StorageFunctionMapping functionMapping = GetFunctionMapping(stateEntry); // create function object FunctionUpdateCommand command = new FunctionUpdateCommand(functionMapping, translator, stateEntry.Source); // bind all function parameters BindFunctionParameters(translator, stateEntry.Source, stateEntry.Original, stateEntry.Current, functionMapping, command); // interpret all result bindings if (null != functionMapping.ResultBindings) { foreach (StorageFunctionResultBinding resultBinding in functionMapping.ResultBindings) { PropagatorResult result = stateEntry.Current.GetMemberValue(resultBinding.Property); command.AddResultColumn(translator, resultBinding.ColumnName, result); } } return command; } private StorageFunctionMapping GetFunctionMapping(ExtractedStateEntry stateEntry) { // choose mapping based on type and operation StorageFunctionMapping functionMapping; EntityType entityType; if (null != stateEntry.Current) { entityType = (EntityType)stateEntry.Current.StructuralType; } else { entityType = (EntityType)stateEntry.Original.StructuralType; } switch (stateEntry.State) { case EntityState.Added: functionMapping = m_typeMappings[entityType].InsertFunctionMapping; break; case EntityState.Deleted: functionMapping = m_typeMappings[entityType].DeleteFunctionMapping; break; case EntityState.Unchanged: case EntityState.Modified: functionMapping = m_typeMappings[entityType].UpdateFunctionMapping; break; default: functionMapping = null; Debug.Fail("unexpected state"); break; } return functionMapping; } // Walks through all parameter bindings in the function mapping and binds the parameters to the // requested properties of the given state entry. private static void BindFunctionParameters(UpdateTranslator translator, IEntityStateEntry stateEntry, PropagatorResult original, PropagatorResult current, StorageFunctionMapping functionMapping, FunctionUpdateCommand command) { // bind all parameters EntityKey entityKey = stateEntry.EntityKey; foreach (StorageFunctionParameterBinding parameterBinding in functionMapping.ParameterBindings) { PropagatorResult result; // extract value if (null != parameterBinding.MemberPath.AssociationSetEnd) { result = RetrieveNavigationResult(translator, command, entityKey, parameterBinding); } else { // walk through the member path to find the appropriate propagator results result = parameterBinding.IsCurrent ? current : original; for (int i = parameterBinding.MemberPath.Members.Count; i > 0;) { --i; EdmMember member = parameterBinding.MemberPath.Members[i]; result = result.GetMemberValue(member); } } // create DbParameter command.SetParameterValue(result, parameterBinding, translator); } // Add rows affected parameter command.RegisterRowsAffectedParameter(functionMapping.RowsAffectedParameter); } // Retrieves the value of a function parameter binding to a relationship navigation value private static PropagatorResult RetrieveNavigationResult(UpdateTranslator translator, FunctionUpdateCommand command, EntityKey entityKey, StorageFunctionParameterBinding parameterBinding) { // Retrieve information about the navigation Debug.Assert(null != parameterBinding.MemberPath.AssociationSetEnd); AssociationSetEnd associationSetEnd = parameterBinding.MemberPath.AssociationSetEnd; AssociationSet associationSet = associationSetEnd.ParentAssociationSet; Debug.Assert(2 == parameterBinding.MemberPath.Members.Count, "association navigation member path " + "must consist of (exactly) one key property and one end member"); EdmProperty keyProperty = (EdmProperty)parameterBinding.MemberPath.Members[0]; AssociationEndMember endMember = parameterBinding.MemberPath.AssociationSetEnd.CorrespondingAssociationEndMember; // Find the relationship entry corresponding to the navigation IEntityStateEntry relationshipEntry = RetrieveNavigationStateEntry(translator, command, entityKey, associationSet, endMember, parameterBinding.IsCurrent); if (null == relationshipEntry) { // if no relationship entry was found, make sure it isn't required if (endMember.RelationshipMultiplicity == RelationshipMultiplicity.One) { string entitySetName = entityKey.EntitySetName; string associationSetName = associationSet.Name; throw EntityUtil.Update(Strings.Update_MissingRequiredRelationshipValue(entitySetName, associationSetName), null, command.GetStateEntries(translator)); } else { // return NULL value return PropagatorResult.CreateSimpleValue(PropagatorFlags.NoFlags, null); } } else { // remember that this entry is "in scope" for the relationship command.RegisterStateEntry(relationshipEntry); // get the actual value PropagatorResult relationshipResult = parameterBinding.IsCurrent ? translator.RecordConverter.ConvertCurrentValuesToPropagatorResult(relationshipEntry, null) : translator.RecordConverter.ConvertOriginalValuesToPropagatorResult(relationshipEntry, null); PropagatorResult endResult = relationshipResult.GetMemberValue(endMember); PropagatorResult keyResult = endResult.GetMemberValue(keyProperty); return keyResult; } } // Tries to find a state entry correspdonding to the given navigation, where "entityKey" is // the key of the parent. private static IEntityStateEntry RetrieveNavigationStateEntry(UpdateTranslator translator, FunctionUpdateCommand command, EntityKey entityKey, AssociationSet associationSetNavigation, AssociationEndMember endMember, bool isCurrent) { IEntityStateEntry relationshipEntry = null; foreach (IEntityStateEntry candidateEntry in translator.GetRelationships(entityKey)) { // check if this is the correct relationship entry if (candidateEntry.EntitySet.EdmEquals(associationSetNavigation)) { // get record containing values DbDataRecord record; if (isCurrent) { if (EntityState.Added == candidateEntry.State || EntityState.Unchanged == candidateEntry.State) { record = candidateEntry.CurrentValues; } else { // wrong version of the relationship continue; } } else { if (EntityState.Deleted == candidateEntry.State || EntityState.Unchanged == candidateEntry.State) { record = candidateEntry.OriginalValues; } else { // wrong version of the relationship continue; } } // find the end corresponding to the 'to' end int toOrdinal = record.GetOrdinal(endMember.Name); Debug.Assert(-1 != toOrdinal, "to end of relationship doesn't exist in record"); // the 'from' end must be the other end int fromOrdinal = 0 == toOrdinal ? 1 : 0; EntityKey fromKey = (EntityKey)record[fromOrdinal]; EntityKey toKey = (EntityKey)record[toOrdinal]; // check we're dealing with the correct relationship direction by looking at the from key if (fromKey == entityKey) { // we've found our match relationshipEntry = candidateEntry; break; } } } return relationshipEntry; } } private sealed class AssociationSetFunctionMappingTranslator : FunctionMappingTranslator { // If this value is null, it indicates that the association set is // only implicitly mapped as part of an entity set private readonly StorageAssociationSetFunctionMapping m_mapping; internal AssociationSetFunctionMappingTranslator(StorageAssociationSetMapping setMapping) { if (null != setMapping) { m_mapping = setMapping.FunctionMapping; } } internal override FunctionUpdateCommand Translate( UpdateTranslator translator, ExtractedStateEntry stateEntry) { if (null == m_mapping) { return null; } bool isInsert = EntityState.Added == stateEntry.State; // initialize a new command StorageFunctionMapping functionMapping = isInsert ? m_mapping.InsertFunctionMapping : m_mapping.DeleteFunctionMapping; FunctionUpdateCommand command = new FunctionUpdateCommand(functionMapping, translator, stateEntry.Source); // extract the relationship values from the state entry PropagatorResult recordResult; if (isInsert) { recordResult = stateEntry.Current; } else { recordResult = stateEntry.Original; } // bind parameters foreach (StorageFunctionParameterBinding parameterBinding in functionMapping.ParameterBindings) { // extract the relationship information Debug.Assert(2 == parameterBinding.MemberPath.Members.Count, "relationship parameter binding member " + "path should include the relationship end and key property only"); EdmProperty keyProperty = (EdmProperty)parameterBinding.MemberPath.Members[0]; AssociationEndMember endMember = (AssociationEndMember)parameterBinding.MemberPath.Members[1]; // get the end member PropagatorResult endResult = recordResult.GetMemberValue(endMember); PropagatorResult keyResult = endResult.GetMemberValue(keyProperty); command.SetParameterValue(keyResult, parameterBinding, translator); } // add rows affected output parameter command.RegisterRowsAffectedParameter(functionMapping.RowsAffectedParameter); return command; } } } } // 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
- DesignerToolboxInfo.cs
- exports.cs
- ConfigurationStrings.cs
- DBConcurrencyException.cs
- TagPrefixInfo.cs
- EmptyEnumerator.cs
- basecomparevalidator.cs
- DPTypeDescriptorContext.cs
- Context.cs
- LinearGradientBrush.cs
- XamlToRtfWriter.cs
- DocumentReferenceCollection.cs
- ServicePointManager.cs
- RightsManagementInformation.cs
- DataGridViewRowHeightInfoNeededEventArgs.cs
- AttributeProviderAttribute.cs
- InternalEnumValidator.cs
- SafeTokenHandle.cs
- PeerObject.cs
- StrongName.cs
- MessageDescriptionCollection.cs
- ApplicationFileCodeDomTreeGenerator.cs
- ProvidersHelper.cs
- MethodExpression.cs
- Schema.cs
- PartDesigner.cs
- PeerNearMe.cs
- SHA256Managed.cs
- AttributeQuery.cs
- PrivacyNoticeBindingElementImporter.cs
- ToolStripSystemRenderer.cs
- AnnotationMap.cs
- ManagementPath.cs
- Activation.cs
- BeginEvent.cs
- DataErrorValidationRule.cs
- HistoryEventArgs.cs
- InputProviderSite.cs
- TypeListConverter.cs
- AxWrapperGen.cs
- TrackingServices.cs
- DesignTimeResourceProviderFactoryAttribute.cs
- BeginEvent.cs
- SystemPens.cs
- ClientSettingsProvider.cs
- CompiledQueryCacheEntry.cs
- SqlUserDefinedAggregateAttribute.cs
- PropertyRef.cs
- QilUnary.cs
- ViewGenerator.cs
- Rule.cs
- ExtensibleSyndicationObject.cs
- InputMethodStateChangeEventArgs.cs
- ExpressionEditorAttribute.cs
- ConfigPathUtility.cs
- Process.cs
- RestHandlerFactory.cs
- DataRowComparer.cs
- Button.cs
- SecurityUtils.cs
- CommentAction.cs
- MarkupExtensionParser.cs
- XmlUrlResolver.cs
- TextFindEngine.cs
- SmiEventSink_DeferedProcessing.cs
- InkCanvas.cs
- BaseTemplateBuildProvider.cs
- SelectionPattern.cs
- InstanceDataCollection.cs
- ExpressionNormalizer.cs
- BuildProviderAppliesToAttribute.cs
- InteropAutomationProvider.cs
- PrimaryKeyTypeConverter.cs
- OrderingInfo.cs
- SecurityUtils.cs
- Single.cs
- InspectionWorker.cs
- SevenBitStream.cs
- ScrollProperties.cs
- TraceLevelStore.cs
- ScriptingWebServicesSectionGroup.cs
- ServiceModelActivity.cs
- SQLGuid.cs
- StopRoutingHandler.cs
- QueryCacheEntry.cs
- Splitter.cs
- ZipIOLocalFileBlock.cs
- BrowserCapabilitiesFactory.cs
- CustomTypeDescriptor.cs
- PropertiesTab.cs
- CodeTypeMemberCollection.cs
- ReadOnlyObservableCollection.cs
- BitmapImage.cs
- StateMachineDesignerPaint.cs
- PngBitmapEncoder.cs
- DataGridItemEventArgs.cs
- StringHandle.cs
- ReferenceAssemblyAttribute.cs
- XmlSubtreeReader.cs
- CodeMemberMethod.cs