1 //--------------------------------------------------------------------- 2 // <copyright file="RecordConverter.cs" company="Microsoft"> 3 // Copyright (c) Microsoft Corporation. All rights reserved. 4 // </copyright> 5 // 6 // @owner Microsoft 7 // @backupOwner Microsoft 8 //--------------------------------------------------------------------- 9 10 namespace System.Data.Mapping.Update.Internal 11 { 12 using System.Data.Entity; 13 14 /// <summary> 15 /// Converts records to new instance expressions. Assumes that all inputs come from a single data reader (because 16 /// it caches record layout). If multiple readers are used, multiple converters must be constructed in case 17 /// the different readers return different layouts for types. 18 /// </summary> 19 /// <remarks> 20 /// Conventions for modifiedProperties enumeration: null means all properties are modified, empty means none, 21 /// non-empty means some. 22 /// </remarks> 23 internal class RecordConverter 24 { 25 #region Constructors 26 /// <summary> 27 /// Initializes a new converter given a command tree context. Initializes a new record layout cache. 28 /// </summary> 29 /// <param name="updateTranslator">Sets <see cref="m_updateTranslator" /></param> RecordConverter(UpdateTranslator updateTranslator)30 internal RecordConverter(UpdateTranslator updateTranslator) 31 { 32 m_updateTranslator = updateTranslator; 33 } 34 #endregion 35 36 #region Fields 37 /// <summary> 38 /// Context used to produce expressions. 39 /// </summary> 40 private UpdateTranslator m_updateTranslator; 41 #endregion 42 43 #region Methods 44 /// <summary> 45 /// Converts original values in a state entry to a DbNewInstanceExpression. The record must be either an entity or 46 /// a relationship set instance. 47 /// </summary> 48 /// <remarks> 49 /// This method is not thread safe. 50 /// </remarks> 51 /// <param name="stateEntry">Gets state entry this record is associated with.</param> 52 /// <param name="modifiedPropertiesBehavior">Indicates how to determine whether a property is modified.</param> 53 /// <returns>New instance expression.</returns> ConvertOriginalValuesToPropagatorResult(IEntityStateEntry stateEntry, ModifiedPropertiesBehavior modifiedPropertiesBehavior)54 internal PropagatorResult ConvertOriginalValuesToPropagatorResult(IEntityStateEntry stateEntry, ModifiedPropertiesBehavior modifiedPropertiesBehavior) 55 { 56 return ConvertStateEntryToPropagatorResult(stateEntry, useCurrentValues: false, modifiedPropertiesBehavior: modifiedPropertiesBehavior); 57 } 58 59 /// <summary> 60 /// Converts current values in a state entry to a DbNewInstanceExpression. The record must be either an entity or 61 /// a relationship set instance. 62 /// </summary> 63 /// <remarks> 64 /// This method is not thread safe. 65 /// </remarks> 66 /// <param name="stateEntry">Gets state entry this record is associated with.</param> 67 /// <param name="modifiedPropertiesBehavior">Indicates how to determine whether a property is modified.</param> 68 /// <returns>New instance expression.</returns> ConvertCurrentValuesToPropagatorResult(IEntityStateEntry stateEntry, ModifiedPropertiesBehavior modifiedPropertiesBehavior)69 internal PropagatorResult ConvertCurrentValuesToPropagatorResult(IEntityStateEntry stateEntry, ModifiedPropertiesBehavior modifiedPropertiesBehavior) 70 { 71 return ConvertStateEntryToPropagatorResult(stateEntry, useCurrentValues: true, modifiedPropertiesBehavior: modifiedPropertiesBehavior); 72 } 73 ConvertStateEntryToPropagatorResult(IEntityStateEntry stateEntry, bool useCurrentValues, ModifiedPropertiesBehavior modifiedPropertiesBehavior)74 private PropagatorResult ConvertStateEntryToPropagatorResult(IEntityStateEntry stateEntry, bool useCurrentValues, ModifiedPropertiesBehavior modifiedPropertiesBehavior) 75 { 76 try 77 { 78 EntityUtil.CheckArgumentNull(stateEntry, "stateEntry"); 79 IExtendedDataRecord record = useCurrentValues 80 ? EntityUtil.CheckArgumentNull(stateEntry.CurrentValues as IExtendedDataRecord, "stateEntry.CurrentValues") 81 : EntityUtil.CheckArgumentNull(stateEntry.OriginalValues as IExtendedDataRecord, "stateEntry.OriginalValues"); 82 83 bool isModified = false; // the root of the state entry is unchanged because the type is static 84 return ExtractorMetadata.ExtractResultFromRecord(stateEntry, isModified, record, useCurrentValues, m_updateTranslator, modifiedPropertiesBehavior); 85 } 86 catch (Exception e) 87 { 88 if (UpdateTranslator.RequiresContext(e)) 89 { 90 throw EntityUtil.Update(Strings.Update_ErrorLoadingRecord, e, stateEntry); 91 } 92 throw; 93 } 94 } 95 #endregion 96 } 97 } 98