Beispiel #1
0
        /// <summary>
        /// Construct a new propagator.
        /// </summary>
        /// <param name="parent">UpdateTranslator supporting retrieval of changes for C-Space
        /// extents referenced in the update mapping view.</param>
        /// <param name="table">Table for which updates are being produced.</param>
        private Propagator(UpdateTranslator parent, EntitySet table)
        {
            // Initialize propagator state.
            EntityUtil.CheckArgumentNull(parent, "parent");
            EntityUtil.CheckArgumentNull(table, "table");

            m_updateTranslator = parent;
            m_table            = table;
        }
Beispiel #2
0
        // <summary>
        // Construct a new propagator.
        // </summary>
        // <param name="parent"> UpdateTranslator supporting retrieval of changes for C-Space extents referenced in the update mapping view. </param>
        // <param name="table"> Table for which updates are being produced. </param>
        private Propagator(UpdateTranslator parent, EntitySet table)
        {
            // Initialize propagator state.
            DebugCheck.NotNull(parent);
            DebugCheck.NotNull(table);

            m_updateTranslator = parent;
            m_table            = table;
        }
 protected UpdateCommand(
     UpdateTranslator translator,
     PropagatorResult originalValues,
     PropagatorResult currentValues)
 {
     this.OriginalValues = originalValues;
     this.CurrentValues  = currentValues;
     this.Translator     = translator;
 }
 /// <summary>
 ///     Initialize a new function command. Initializes the command object.
 /// </summary>
 /// <param name="functionMapping"> Function mapping metadata </param>
 /// <param name="translator"> Translator </param>
 /// <param name="stateEntries"> State entries handled by this operation. </param>
 /// <param name="stateEntry"> 'Root' state entry being handled by this function. </param>
 internal FunctionUpdateCommand(
     StorageModificationFunctionMapping functionMapping, UpdateTranslator translator,
     ReadOnlyCollection <IEntityStateEntry> stateEntries, ExtractedStateEntry stateEntry)
     : this(translator, stateEntries, stateEntry,
            translator.GenerateCommandDefinition(functionMapping).CreateCommand())
 {
     DebugCheck.NotNull(functionMapping);
     DebugCheck.NotNull(translator);
     DebugCheck.NotNull(stateEntries);
 }
Beispiel #5
0
        public string GetQueryWithParameter(Expression fieldUpdate, Expression where, object source)
        {
            StringBuilder sb = new StringBuilder();

            var translator = new UpdateTranslator(ref command);

            sb.Append(translator.Translate(fieldUpdate, source));
            sb.Append(" where ").Append(new WhereTranslator().Translate(where));
            return(sb.ToString());
        }
        internal static ReadOnlyCollection <IEntityStateEntry> GetAllStateEntries(
            PropagatorResult source,
            UpdateTranslator translator,
            EntitySet sourceTable)
        {
            SourceInterpreter sourceInterpreter = new SourceInterpreter(translator, sourceTable);

            sourceInterpreter.RetrieveResultMarkup(source);
            return(new ReadOnlyCollection <IEntityStateEntry>((IList <IEntityStateEntry>)sourceInterpreter.m_stateEntries));
        }
 /// <summary>
 /// Initialize a new function command. Initializes the command object.
 /// </summary>
 /// <param name="functionMapping">Function mapping metadata</param>
 /// <param name="translator">Translator</param>
 /// <param name="stateEntries">State entries handled by this operation.</param>
 /// <param name="stateEntry">'Root' state entry being handled by this function.</param>
 internal FunctionUpdateCommand(
     StorageModificationFunctionMapping functionMapping, UpdateTranslator translator,
     ReadOnlyCollection<IEntityStateEntry> stateEntries, ExtractedStateEntry stateEntry)
     : this(translator, stateEntries, stateEntry,
         translator.GenerateCommandDefinition(functionMapping).CreateCommand())
 {
     Contract.Requires(functionMapping != null);
     Contract.Requires(translator != null);
     Contract.Requires(stateEntries != null);
 }
Beispiel #8
0
 protected FunctionUpdateCommand(
     UpdateTranslator translator,
     ReadOnlyCollection <System.Data.Entity.Core.IEntityStateEntry> stateEntries,
     ExtractedStateEntry stateEntry,
     DbCommand dbCommand)
     : base(translator, stateEntry.Original, stateEntry.Current)
 {
     this._stateEntries = stateEntries;
     this._dbCommand    = (DbCommand) new InterceptableDbCommand(dbCommand, translator.InterceptionContext, (DbDispatchers)null);
 }
        protected FunctionUpdateCommand(
            UpdateTranslator translator, ReadOnlyCollection<IEntityStateEntry> stateEntries, ExtractedStateEntry stateEntry,
            DbCommand dbCommand)
            : base(translator, stateEntry.Original, stateEntry.Current)
        {
            // populate the main state entry for error reporting
            _stateEntries = stateEntries;

            _dbCommand = dbCommand;
        }
        protected FunctionUpdateCommand(
            UpdateTranslator translator, ReadOnlyCollection <IEntityStateEntry> stateEntries, ExtractedStateEntry stateEntry,
            DbCommand dbCommand)
            : base(translator, stateEntry.Original, stateEntry.Current)
        {
            // populate the main state entry for error reporting
            _stateEntries = stateEntries;

            _dbCommand = dbCommand;
        }
            internal override FunctionUpdateCommand Translate(
                UpdateTranslator translator,
                ExtractedStateEntry stateEntry)
            {
                if (null == m_mapping)
                {
                    return(null);
                }

                var isInsert = EntityState.Added == stateEntry.State;

                EntityUtil.ValidateNecessaryModificationFunctionMapping(
                    isInsert ? m_mapping.InsertFunctionMapping : m_mapping.DeleteFunctionMapping,
                    isInsert ? "Insert" : "Delete",
                    stateEntry.Source, "AssociationSet", m_mapping.AssociationSet.Name);

                // initialize a new command
                var functionMapping = isInsert ? m_mapping.InsertFunctionMapping : m_mapping.DeleteFunctionMapping;
                var command         = new FunctionUpdateCommand(
                    functionMapping, translator, new ReadOnlyCollection <IEntityStateEntry>(new[] { stateEntry.Source }.ToList()), stateEntry);

                // extract the relationship values from the state entry
                PropagatorResult recordResult;

                if (isInsert)
                {
                    recordResult = stateEntry.Current;
                }
                else
                {
                    recordResult = stateEntry.Original;
                }

                // bind parameters
                foreach (var 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");

                    var keyProperty = (EdmProperty)parameterBinding.MemberPath.Members[0];
                    var endMember   = (AssociationEndMember)parameterBinding.MemberPath.Members[1];

                    // get the end member
                    var endResult = recordResult.GetMemberValue(endMember);
                    var keyResult = endResult.GetMemberValue(keyProperty);

                    command.SetParameterValue(keyResult, parameterBinding, translator);
                }
                // add rows affected output parameter
                command.RegisterRowsAffectedParameter(functionMapping.RowsAffectedParameter);

                return(command);
            }
 /// <summary>
 ///     Initialize a new function command. Initializes the command object.
 /// </summary>
 /// <param name="functionMapping"> Function mapping metadata </param>
 /// <param name="translator"> Translator </param>
 /// <param name="stateEntries"> State entries handled by this operation. </param>
 /// <param name="stateEntry"> 'Root' state entry being handled by this function. </param>
 internal FunctionUpdateCommand(
     StorageModificationFunctionMapping functionMapping,
     UpdateTranslator translator,
     ReadOnlyCollection<IEntityStateEntry> stateEntries,
     ExtractedStateEntry stateEntry)
     : this(translator, stateEntries, stateEntry,
         translator.GenerateCommandDefinition(functionMapping).CreateCommand())
 {
     DebugCheck.NotNull(functionMapping);
     DebugCheck.NotNull(translator);
     DebugCheck.NotNull(stateEntries);
 }
Beispiel #13
0
        // <summary>
        // Propagate changes from C-Space (contained in <paramref name="parent" /> to the S-Space.
        // </summary>
        // <remarks>
        // See Walker class for an explanation of this coding pattern.
        // </remarks>
        // <param name="parent"> Grouper supporting retrieval of changes for C-Space extents referenced in the update mapping view. </param>
        // <param name="table"> Table for which updates are being produced. </param>
        // <param name="umView"> Update mapping view to propagate. </param>
        // <returns> Changes in S-Space. </returns>
        internal static ChangeNode Propagate(UpdateTranslator parent, EntitySet table, DbQueryCommandTree umView)
        {
            // Construct a new instance of a propagator, which implements a visitor interface
            // for expression nodes (nodes in the update mapping view) and returns changes nodes
            // (seeded by C-Space extent changes returned by the grouper).
            DbExpressionVisitor <ChangeNode> propagator = new Propagator(parent, table);

            // Walk the update mapping view using the visitor pattern implemented in this class.
            // The update mapping view describes the S-Space table we're targeting, so the result
            // returned for the root of view corresponds to changes propagated to the S-Space.
            return(umView.Query.Accept(propagator));
        }
        // <summary>
        // Finds all markup associated with the given source.
        // </summary>
        // <param name="source"> Source expression. Must not be null. </param>
        // <param name="translator"> Translator containing session information. </param>
        // <param name="sourceTable"> Table from which the exception was thrown (must not be null). </param>
        // <returns> Markup. </returns>
        internal static ReadOnlyCollection<IEntityStateEntry> GetAllStateEntries(
            PropagatorResult source, UpdateTranslator translator,
            EntitySet sourceTable)
        {
            DebugCheck.NotNull(source);
            DebugCheck.NotNull(translator);
            DebugCheck.NotNull(sourceTable);

            var interpreter = new SourceInterpreter(translator, sourceTable);
            interpreter.RetrieveResultMarkup(source);

            return new ReadOnlyCollection<IEntityStateEntry>(interpreter.m_stateEntries);
        }
        /// <summary>
        ///     Finds all markup associated with the given source.
        /// </summary>
        /// <param name="source"> Source expression. Must not be null. </param>
        /// <param name="translator"> Translator containing session information. </param>
        /// <param name="sourceTable"> Table from which the exception was thrown (must not be null). </param>
        /// <returns> Markup. </returns>
        internal static ReadOnlyCollection <IEntityStateEntry> GetAllStateEntries(
            PropagatorResult source, UpdateTranslator translator,
            EntitySet sourceTable)
        {
            DebugCheck.NotNull(source);
            DebugCheck.NotNull(translator);
            DebugCheck.NotNull(sourceTable);

            var interpreter = new SourceInterpreter(translator, sourceTable);

            interpreter.RetrieveResultMarkup(source);

            return(new ReadOnlyCollection <IEntityStateEntry>(interpreter.m_stateEntries));
        }
Beispiel #16
0
 private int GetColumnOrdinal(
     UpdateTranslator translator,
     DbDataReader reader,
     string columnName)
 {
     try
     {
         return(reader.GetOrdinal(columnName));
     }
     catch (IndexOutOfRangeException ex)
     {
         throw new UpdateException(Strings.Update_MissingResultColumn((object)columnName), (Exception)null, this.GetStateEntries(translator).Cast <ObjectStateEntry>().Distinct <ObjectStateEntry>());
     }
 }
        private int GetColumnOrdinal(UpdateTranslator translator, DbDataReader reader, string columnName)
        {
            int columnOrdinal;

            try
            {
                columnOrdinal = reader.GetOrdinal(columnName);
            }
            catch (IndexOutOfRangeException)
            {
                throw new UpdateException(
                          Strings.Update_MissingResultColumn(columnName), null, GetStateEntries(translator).Cast <ObjectStateEntry>().Distinct());
            }
            return(columnOrdinal);
        }
        private int GetColumnOrdinal(UpdateTranslator translator, DbDataReader reader, string columnName)
        {
            int columnOrdinal;

            try
            {
                columnOrdinal = reader.GetOrdinal(columnName);
            }
            catch (IndexOutOfRangeException)
            {
                throw EntityUtil.Update(System.Data.Entity.Strings.Update_MissingResultColumn(columnName), null,
                                        this.GetStateEntries(translator));
            }
            return(columnOrdinal);
        }
        internal void GetRequiredAndProducedEntities(
            UpdateTranslator translator,
            KeyToListMap <EntityKey, UpdateCommand> addedEntities,
            KeyToListMap <EntityKey, UpdateCommand> deletedEntities,
            KeyToListMap <EntityKey, UpdateCommand> addedRelationships,
            KeyToListMap <EntityKey, UpdateCommand> deletedRelationships)
        {
            IList <IEntityStateEntry> stateEntries = this.GetStateEntries(translator);

            foreach (IEntityStateEntry entityStateEntry in (IEnumerable <IEntityStateEntry>)stateEntries)
            {
                if (!entityStateEntry.IsRelationship)
                {
                    if (entityStateEntry.State == EntityState.Added)
                    {
                        addedEntities.Add(entityStateEntry.EntityKey, this);
                    }
                    else if (entityStateEntry.State == EntityState.Deleted)
                    {
                        deletedEntities.Add(entityStateEntry.EntityKey, this);
                    }
                }
            }
            if (this.OriginalValues != null)
            {
                this.AddReferencedEntities(translator, this.OriginalValues, deletedRelationships);
            }
            if (this.CurrentValues != null)
            {
                this.AddReferencedEntities(translator, this.CurrentValues, addedRelationships);
            }
            foreach (IEntityStateEntry entityStateEntry in (IEnumerable <IEntityStateEntry>)stateEntries)
            {
                if (entityStateEntry.IsRelationship)
                {
                    bool flag = entityStateEntry.State == EntityState.Added;
                    if (flag || entityStateEntry.State == EntityState.Deleted)
                    {
                        DbDataRecord dbDataRecord = flag ? (DbDataRecord)entityStateEntry.CurrentValues : entityStateEntry.OriginalValues;
                        EntityKey    key1         = (EntityKey)dbDataRecord[0];
                        EntityKey    key2         = (EntityKey)dbDataRecord[1];
                        KeyToListMap <EntityKey, UpdateCommand> keyToListMap = flag ? addedRelationships : deletedRelationships;
                        keyToListMap.Add(key1, this);
                        keyToListMap.Add(key2, this);
                    }
                }
            }
        }
Beispiel #20
0
        // <summary>
        // Handles extent expressions (these are the terminal nodes in update mapping views). This handler
        // retrieves the changes from the grouper.
        // </summary>
        // <param name="node"> Extent expression node </param>
        public override ChangeNode Visit(DbScanExpression node)
        {
            Check.NotNull(node, "node");

            // Gets modifications requested for this extent from the grouper.
            var extent = node.Target;
            var extentModifications = UpdateTranslator.GetExtentModifications(extent);

            if (null == extentModifications.Placeholder)
            {
                // Bootstrap placeholder (essentially a record for the extent populated with default values).
                extentModifications.Placeholder = ExtentPlaceholderCreator.CreatePlaceholder(extent);
            }

            return(extentModifications);
        }
 private static void BindFunctionParameters(
     UpdateTranslator translator,
     ExtractedStateEntry stateEntry,
     ModificationFunctionMapping functionMapping,
     FunctionUpdateCommand command,
     Dictionary <AssociationEndMember, IEntityStateEntry> currentReferenceEnds,
     Dictionary <AssociationEndMember, IEntityStateEntry> originalReferenceEnds)
 {
     foreach (ModificationFunctionParameterBinding parameterBinding in functionMapping.ParameterBindings)
     {
         PropagatorResult result;
         if (parameterBinding.MemberPath.AssociationSetEnd != null)
         {
             AssociationEndMember associationEndMember = parameterBinding.MemberPath.AssociationSetEnd.CorrespondingAssociationEndMember;
             IEntityStateEntry    stateEntry1;
             if (!(parameterBinding.IsCurrent ? currentReferenceEnds.TryGetValue(associationEndMember, out stateEntry1) : originalReferenceEnds.TryGetValue(associationEndMember, out stateEntry1)))
             {
                 if (associationEndMember.RelationshipMultiplicity == RelationshipMultiplicity.One)
                 {
                     throw new UpdateException(Strings.Update_MissingRequiredRelationshipValue((object)stateEntry.Source.EntitySet.Name, (object)parameterBinding.MemberPath.AssociationSetEnd.ParentAssociationSet.Name), (Exception)null, command.GetStateEntries(translator).Cast <ObjectStateEntry>().Distinct <ObjectStateEntry>());
                 }
                 result = PropagatorResult.CreateSimpleValue(PropagatorFlags.NoFlags, (object)null);
             }
             else
             {
                 result = (parameterBinding.IsCurrent ? translator.RecordConverter.ConvertCurrentValuesToPropagatorResult(stateEntry1, ModifiedPropertiesBehavior.AllModified) : translator.RecordConverter.ConvertOriginalValuesToPropagatorResult(stateEntry1, ModifiedPropertiesBehavior.AllModified)).GetMemberValue((EdmMember)associationEndMember).GetMemberValue(parameterBinding.MemberPath.Members[0]);
             }
         }
         else
         {
             result = parameterBinding.IsCurrent ? stateEntry.Current : stateEntry.Original;
             int count = parameterBinding.MemberPath.Members.Count;
             while (count > 0)
             {
                 --count;
                 EdmMember member = parameterBinding.MemberPath.Members[count];
                 result = result.GetMemberValue(member);
             }
         }
         command.SetParameterValue(result, parameterBinding, translator);
     }
     command.RegisterRowsAffectedParameter(functionMapping.RowsAffectedParameter);
 }
        internal ExtractedStateEntry(UpdateTranslator translator, IEntityStateEntry stateEntry)
        {
            DebugCheck.NotNull(translator);
            DebugCheck.NotNull(stateEntry);

            State  = stateEntry.State;
            Source = stateEntry;

            switch (stateEntry.State)
            {
            case EntityState.Deleted:
                Original = translator.RecordConverter.ConvertOriginalValuesToPropagatorResult(
                    stateEntry, ModifiedPropertiesBehavior.AllModified);
                Current = null;
                break;

            case EntityState.Unchanged:
                Original = translator.RecordConverter.ConvertOriginalValuesToPropagatorResult(
                    stateEntry, ModifiedPropertiesBehavior.NoneModified);
                Current = translator.RecordConverter.ConvertCurrentValuesToPropagatorResult(
                    stateEntry, ModifiedPropertiesBehavior.NoneModified);
                break;

            case EntityState.Modified:
                Original = translator.RecordConverter.ConvertOriginalValuesToPropagatorResult(
                    stateEntry, ModifiedPropertiesBehavior.SomeModified);
                Current = translator.RecordConverter.ConvertCurrentValuesToPropagatorResult(
                    stateEntry, ModifiedPropertiesBehavior.SomeModified);
                break;

            case EntityState.Added:
                Original = null;
                Current  = translator.RecordConverter.ConvertCurrentValuesToPropagatorResult(
                    stateEntry, ModifiedPropertiesBehavior.AllModified);
                break;

            default:
                Debug.Assert(false, "Unexpected IEntityStateEntry.State for entity " + stateEntry.State);
                Original = null;
                Current  = null;
                break;
            }
        }
Beispiel #23
0
        // <summary>
        // Converts a record to a propagator result
        // </summary>
        // <param name="stateEntry"> state manager entry containing the record </param>
        // <param name="isModified"> Indicates whether the root element is modified (i.e., whether the type has changed) </param>
        // <param name="record"> Record to convert </param>
        // <param name="useCurrentValues"> Indicates whether we are retrieving current or original values. </param>
        // <param name="translator"> Translator for session context; registers new metadata for the record type if none exists </param>
        // <param name="modifiedPropertiesBehavior"> Indicates how to determine whether a property is modified. </param>
        // <returns> Result corresponding to the given record </returns>
        internal static PropagatorResult ExtractResultFromRecord(
            IEntityStateEntry stateEntry, bool isModified, IExtendedDataRecord record,
            bool useCurrentValues, UpdateTranslator translator, ModifiedPropertiesBehavior modifiedPropertiesBehavior)
        {
            var structuralType = (StructuralType)record.DataRecordInfo.RecordType.EdmType;
            var metadata       = translator.GetExtractorMetadata(stateEntry.EntitySet, structuralType);
            var key            = stateEntry.EntityKey;

            var nestedValues = new PropagatorResult[record.FieldCount];

            for (var ordinal = 0; ordinal < nestedValues.Length; ordinal++)
            {
                nestedValues[ordinal] = metadata.RetrieveMember(
                    stateEntry, record, useCurrentValues, key,
                    ordinal, modifiedPropertiesBehavior);
            }

            return(PropagatorResult.CreateStructuralValue(nestedValues, structuralType, isModified));
        }
        internal DynamicUpdateCommand(
            TableChangeProcessor processor, UpdateTranslator translator,
            ModificationOperator modificationOperator, PropagatorResult originalValues, PropagatorResult currentValues,
            DbModificationCommandTree tree, Dictionary<int, string> outputIdentifiers)
            : base(translator, originalValues, currentValues)
        {
            Contract.Requires(processor != null);
            Contract.Requires(translator != null);
            Contract.Requires(tree != null);

            _processor = processor;
            _operator = modificationOperator;
            _modificationCommandTree = tree;
            _outputIdentifiers = outputIdentifiers; // may be null (not all commands have output identifiers)

            // initialize identifier information (supports lateral propagation of server gen values)
            if (ModificationOperator.Insert == modificationOperator
                || ModificationOperator.Update == modificationOperator)
            {
                const int capacity = 2; // "average" number of identifiers per row
                _inputIdentifiers = new List<KeyValuePair<int, DbSetClause>>(capacity);

                foreach (var member in
                    Helper.PairEnumerations(
                        TypeHelpers.GetAllStructuralMembers(CurrentValues.StructuralType),
                        CurrentValues.GetMemberValues()))
                {
                    DbSetClause setter;
                    var identifier = member.Value.Identifier;

                    if (PropagatorResult.NullIdentifier != identifier
                        &&
                        TryGetSetterExpression(tree, member.Key, modificationOperator, out setter)) // can find corresponding setter
                    {
                        foreach (var principal in translator.KeyManager.GetPrincipals(identifier))
                        {
                            _inputIdentifiers.Add(new KeyValuePair<int, DbSetClause>(principal, setter));
                        }
                    }
                }
            }
        }
Beispiel #25
0
        internal DynamicUpdateCommand(
            TableChangeProcessor processor, UpdateTranslator translator,
            ModificationOperator modificationOperator, PropagatorResult originalValues, PropagatorResult currentValues,
            DbModificationCommandTree tree, Dictionary <int, string> outputIdentifiers)
            : base(translator, originalValues, currentValues)
        {
            DebugCheck.NotNull(processor);
            DebugCheck.NotNull(translator);
            DebugCheck.NotNull(tree);

            _processor = processor;
            _operator  = modificationOperator;
            _modificationCommandTree = tree;
            _outputIdentifiers       = outputIdentifiers; // may be null (not all commands have output identifiers)

            // initialize identifier information (supports lateral propagation of server gen values)
            if (ModificationOperator.Insert == modificationOperator ||
                ModificationOperator.Update == modificationOperator)
            {
                const int capacity = 2; // "average" number of identifiers per row
                _inputIdentifiers = new List <KeyValuePair <int, DbSetClause> >(capacity);

                foreach (var member in
                         Helper.PairEnumerations(
                             TypeHelpers.GetAllStructuralMembers(CurrentValues.StructuralType),
                             CurrentValues.GetMemberValues()))
                {
                    DbSetClause setter;
                    var         identifier = member.Value.Identifier;

                    if (PropagatorResult.NullIdentifier != identifier
                        &&
                        TryGetSetterExpression(tree, member.Key, modificationOperator, out setter)) // can find corresponding setter
                    {
                        foreach (var principal in translator.KeyManager.GetPrincipals(identifier))
                        {
                            _inputIdentifiers.Add(new KeyValuePair <int, DbSetClause>(principal, setter));
                        }
                    }
                }
            }
        }
 private void AddReferencedEntities(
     UpdateTranslator translator,
     PropagatorResult result,
     KeyToListMap <EntityKey, UpdateCommand> referencedEntities)
 {
     foreach (PropagatorResult memberValue in result.GetMemberValues())
     {
         if (memberValue.IsSimple && memberValue.Identifier != -1 && PropagatorFlags.ForeignKey == (memberValue.PropagatorFlags & PropagatorFlags.ForeignKey))
         {
             foreach (int directReference in translator.KeyManager.GetDirectReferences(memberValue.Identifier))
             {
                 PropagatorResult owner;
                 if (translator.KeyManager.TryGetIdentifierOwner(directReference, out owner) && owner.StateEntry != null)
                 {
                     referencedEntities.Add(owner.StateEntry.EntityKey, this);
                 }
             }
         }
     }
 }
 private void AddReferencedEntities(UpdateTranslator translator, PropagatorResult result, KeyToListMap <EntityKey, UpdateCommand> referencedEntities)
 {
     foreach (PropagatorResult property in result.GetMemberValues())
     {
         if (property.IsSimple && property.Identifier != PropagatorResult.NullIdentifier &&
             (PropagatorFlags.ForeignKey == (property.PropagatorFlags & PropagatorFlags.ForeignKey)))
         {
             foreach (int principal in translator.KeyManager.GetDirectReferences(property.Identifier))
             {
                 PropagatorResult owner;
                 if (translator.KeyManager.TryGetIdentifierOwner(principal, out owner) &&
                     null != owner.StateEntry)
                 {
                     Debug.Assert(!owner.StateEntry.IsRelationship, "owner must not be a relationship");
                     referencedEntities.Add(owner.StateEntry.EntityKey, this);
                 }
             }
         }
     }
 }
Beispiel #28
0
        internal ExtractedStateEntry(UpdateTranslator translator, IEntityStateEntry stateEntry)
        {
            Debug.Assert(null != stateEntry, "stateEntry must not be null");
            this.State  = stateEntry.State;
            this.Source = stateEntry;

            switch (stateEntry.State)
            {
            case EntityState.Deleted:
                this.Original = translator.RecordConverter.ConvertOriginalValuesToPropagatorResult(
                    stateEntry, ModifiedPropertiesBehavior.AllModified);
                this.Current = null;
                break;

            case EntityState.Unchanged:
                this.Original = translator.RecordConverter.ConvertOriginalValuesToPropagatorResult(
                    stateEntry, ModifiedPropertiesBehavior.NoneModified);
                this.Current = translator.RecordConverter.ConvertCurrentValuesToPropagatorResult(
                    stateEntry, ModifiedPropertiesBehavior.NoneModified);
                break;

            case EntityState.Modified:
                this.Original = translator.RecordConverter.ConvertOriginalValuesToPropagatorResult(
                    stateEntry, ModifiedPropertiesBehavior.SomeModified);
                this.Current = translator.RecordConverter.ConvertCurrentValuesToPropagatorResult(
                    stateEntry, ModifiedPropertiesBehavior.SomeModified);
                break;

            case EntityState.Added:
                this.Original = null;
                this.Current  = translator.RecordConverter.ConvertCurrentValuesToPropagatorResult(
                    stateEntry, ModifiedPropertiesBehavior.AllModified);
                break;

            default:
                Debug.Fail("unexpected IEntityStateEntry.State for entity " + stateEntry.State);
                this.Original = null;
                this.Current  = null;
                break;
            }
        }
        private PropagatorResult ConvertStateEntryToPropagatorResult(IEntityStateEntry stateEntry, bool useCurrentValues, ModifiedPropertiesBehavior modifiedPropertiesBehavior)
        {
            try
            {
                EntityUtil.CheckArgumentNull(stateEntry, "stateEntry");
                IExtendedDataRecord record = useCurrentValues
                    ? EntityUtil.CheckArgumentNull(stateEntry.CurrentValues as IExtendedDataRecord, "stateEntry.CurrentValues")
                    : EntityUtil.CheckArgumentNull(stateEntry.OriginalValues as IExtendedDataRecord, "stateEntry.OriginalValues");

                bool isModified = false; // the root of the state entry is unchanged because the type is static
                return(ExtractorMetadata.ExtractResultFromRecord(stateEntry, isModified, record, useCurrentValues, m_updateTranslator, modifiedPropertiesBehavior));
            }
            catch (Exception e)
            {
                if (UpdateTranslator.RequiresContext(e))
                {
                    throw EntityUtil.Update(Strings.Update_ErrorLoadingRecord, e, stateEntry);
                }
                throw;
            }
        }
Beispiel #30
0
        internal override IList <IEntityStateEntry> GetStateEntries(
            UpdateTranslator translator)
        {
            List <IEntityStateEntry> entityStateEntryList = new List <IEntityStateEntry>(2);

            if (this.OriginalValues != null)
            {
                foreach (IEntityStateEntry allStateEntry in SourceInterpreter.GetAllStateEntries(this.OriginalValues, translator, this.Table))
                {
                    entityStateEntryList.Add(allStateEntry);
                }
            }
            if (this.CurrentValues != null)
            {
                foreach (IEntityStateEntry allStateEntry in SourceInterpreter.GetAllStateEntries(this.CurrentValues, translator, this.Table))
                {
                    entityStateEntryList.Add(allStateEntry);
                }
            }
            return((IList <IEntityStateEntry>)entityStateEntryList);
        }
        internal ExtractedStateEntry(UpdateTranslator translator, IEntityStateEntry stateEntry)
        {
            DebugCheck.NotNull(translator);
            DebugCheck.NotNull(stateEntry);

            State = stateEntry.State;
            Source = stateEntry;

            switch (stateEntry.State)
            {
                case EntityState.Deleted:
                    Original = translator.RecordConverter.ConvertOriginalValuesToPropagatorResult(
                        stateEntry, ModifiedPropertiesBehavior.AllModified);
                    Current = null;
                    break;
                case EntityState.Unchanged:
                    Original = translator.RecordConverter.ConvertOriginalValuesToPropagatorResult(
                        stateEntry, ModifiedPropertiesBehavior.NoneModified);
                    Current = translator.RecordConverter.ConvertCurrentValuesToPropagatorResult(
                        stateEntry, ModifiedPropertiesBehavior.NoneModified);
                    break;
                case EntityState.Modified:
                    Original = translator.RecordConverter.ConvertOriginalValuesToPropagatorResult(
                        stateEntry, ModifiedPropertiesBehavior.SomeModified);
                    Current = translator.RecordConverter.ConvertCurrentValuesToPropagatorResult(
                        stateEntry, ModifiedPropertiesBehavior.SomeModified);
                    break;
                case EntityState.Added:
                    Original = null;
                    Current = translator.RecordConverter.ConvertCurrentValuesToPropagatorResult(
                        stateEntry, ModifiedPropertiesBehavior.AllModified);
                    break;
                default:
                    Debug.Assert(false, "Unexpected IEntityStateEntry.State for entity " + stateEntry.State);
                    Original = null;
                    Current = null;
                    break;
            }
        }
        private T Update <T>(T noChangesResult, Func <UpdateTranslator, T> updateFunction)
        {
            if (!EntityAdapter.IsStateManagerDirty(this._context.ObjectStateManager))
            {
                return(noChangesResult);
            }
            if (this._connection == null)
            {
                throw Error.EntityClient_NoConnectionForAdapter();
            }
            if (this._connection.StoreProviderFactory == null || this._connection.StoreConnection == null)
            {
                throw Error.EntityClient_NoStoreConnectionForUpdate();
            }
            if (ConnectionState.Open != this._connection.State)
            {
                throw Error.EntityClient_ClosedConnectionForUpdate();
            }
            UpdateTranslator updateTranslator = this._updateTranslatorFactory(this);

            return(updateFunction(updateTranslator));
        }
Beispiel #33
0
        internal void AddResultColumn(
            UpdateTranslator translator,
            string columnName,
            PropagatorResult result)
        {
            if (this.ResultColumns == null)
            {
                this.ResultColumns = new List <KeyValuePair <string, PropagatorResult> >(2);
            }
            this.ResultColumns.Add(new KeyValuePair <string, PropagatorResult>(columnName, result));
            int identifier = result.Identifier;

            if (-1 == identifier)
            {
                return;
            }
            if (translator.KeyManager.HasPrincipals(identifier))
            {
                throw new InvalidOperationException(Strings.Update_GeneratedDependent((object)columnName));
            }
            this.AddOutputIdentifier(columnName, identifier);
        }
            internal override FunctionUpdateCommand Translate(
                UpdateTranslator translator,
                ExtractedStateEntry stateEntry)
            {
                ModificationFunctionMapping functionMapping = this.GetFunctionMapping(stateEntry).Item2;
                EntityKey entityKey = stateEntry.Source.EntityKey;
                HashSet <IEntityStateEntry> entityStateEntrySet = new HashSet <IEntityStateEntry>()
                {
                    stateEntry.Source
                };
                IEnumerable <Tuple <AssociationEndMember, IEntityStateEntry> > tuples      = functionMapping.CollocatedAssociationSetEnds.Join <AssociationSetEnd, IEntityStateEntry, StructuralType, Tuple <AssociationEndMember, IEntityStateEntry> >(translator.GetRelationships(entityKey), (Func <AssociationSetEnd, StructuralType>)(end => end.CorrespondingAssociationEndMember.DeclaringType), (Func <IEntityStateEntry, StructuralType>)(candidateEntry => (StructuralType)candidateEntry.EntitySet.ElementType), (Func <AssociationSetEnd, IEntityStateEntry, Tuple <AssociationEndMember, IEntityStateEntry> >)((end, candidateEntry) => Tuple.Create <AssociationEndMember, IEntityStateEntry>(end.CorrespondingAssociationEndMember, candidateEntry)));
                Dictionary <AssociationEndMember, IEntityStateEntry>           dictionary1 = new Dictionary <AssociationEndMember, IEntityStateEntry>();
                Dictionary <AssociationEndMember, IEntityStateEntry>           dictionary2 = new Dictionary <AssociationEndMember, IEntityStateEntry>();

                foreach (Tuple <AssociationEndMember, IEntityStateEntry> tuple in tuples)
                {
                    ModificationFunctionMappingTranslator.EntitySetTranslator.ProcessReferenceCandidate(entityKey, entityStateEntrySet, dictionary1, dictionary2, tuple.Item1, tuple.Item2);
                }
                FunctionUpdateCommand command;

                if (entityStateEntrySet.All <IEntityStateEntry>((Func <IEntityStateEntry, bool>)(e => e.State == EntityState.Unchanged)))
                {
                    command = (FunctionUpdateCommand)null;
                }
                else
                {
                    command = new FunctionUpdateCommand(functionMapping, translator, new ReadOnlyCollection <IEntityStateEntry>((IList <IEntityStateEntry>)entityStateEntrySet.ToList <IEntityStateEntry>()), stateEntry);
                    ModificationFunctionMappingTranslator.EntitySetTranslator.BindFunctionParameters(translator, stateEntry, functionMapping, command, dictionary1, dictionary2);
                    if (functionMapping.ResultBindings != null)
                    {
                        foreach (ModificationFunctionResultBinding resultBinding in functionMapping.ResultBindings)
                        {
                            PropagatorResult memberValue = stateEntry.Current.GetMemberValue((EdmMember)resultBinding.Property);
                            command.AddResultColumn(translator, resultBinding.ColumnName, memberValue);
                        }
                    }
                }
                return(command);
            }
Beispiel #35
0
        internal override IList <IEntityStateEntry> GetStateEntries(UpdateTranslator translator)
        {
            var stateEntries = new List <IEntityStateEntry>(2);

            if (null != OriginalValues)
            {
                foreach (var stateEntry in SourceInterpreter.GetAllStateEntries(
                             OriginalValues, translator, Table))
                {
                    stateEntries.Add(stateEntry);
                }
            }

            if (null != CurrentValues)
            {
                foreach (var stateEntry in SourceInterpreter.GetAllStateEntries(
                             CurrentValues, translator, Table))
                {
                    stateEntries.Add(stateEntry);
                }
            }
            return(stateEntries);
        }
        // Adds a result column binding from a column name (from the result set for the function) to
        // a propagator result (which contains the context necessary to back-propagate the result).
        // If the result is an identifier, binds the
        internal void AddResultColumn(UpdateTranslator translator, String columnName, PropagatorResult result)
        {
            const int initializeSize = 2; // expect on average less than two result columns per command

            if (null == ResultColumns)
            {
                ResultColumns = new List <KeyValuePair <string, PropagatorResult> >(initializeSize);
            }
            ResultColumns.Add(new KeyValuePair <string, PropagatorResult>(columnName, result));

            var identifier = result.Identifier;

            if (PropagatorResult.NullIdentifier != identifier)
            {
                if (translator.KeyManager.HasPrincipals(identifier))
                {
                    throw new InvalidOperationException(Strings.Update_GeneratedDependent(columnName));
                }

                // register output identifier to enable fix-up and dependency tracking
                AddOutputIdentifier(columnName, identifier);
            }
        }
            // 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, ExtractedStateEntry stateEntry, ModificationFunctionMapping functionMapping,
                FunctionUpdateCommand command, Dictionary<AssociationEndMember, IEntityStateEntry> currentReferenceEnds,
                Dictionary<AssociationEndMember, IEntityStateEntry> originalReferenceEnds)
            {
                // bind all parameters
                foreach (var parameterBinding in functionMapping.ParameterBindings)
                {
                    PropagatorResult result;

                    // extract value
                    if (null != parameterBinding.MemberPath.AssociationSetEnd)
                    {
                        // find the relationship entry corresponding to the navigation
                        var endMember = parameterBinding.MemberPath.AssociationSetEnd.CorrespondingAssociationEndMember;
                        IEntityStateEntry relationshipEntry;
                        var hasTarget = parameterBinding.IsCurrent
                                            ? currentReferenceEnds.TryGetValue(endMember, out relationshipEntry)
                                            : originalReferenceEnds.TryGetValue(endMember, out relationshipEntry);
                        if (!hasTarget)
                        {
                            if (endMember.RelationshipMultiplicity
                                == RelationshipMultiplicity.One)
                            {
                                var entitySetName = stateEntry.Source.EntitySet.Name;
                                var associationSetName = parameterBinding.MemberPath.AssociationSetEnd.ParentAssociationSet.Name;
                                throw new UpdateException(
                                    Strings.Update_MissingRequiredRelationshipValue(entitySetName, associationSetName), null,
                                    command.GetStateEntries(translator).Cast<ObjectStateEntry>().Distinct());
                            }
                            else
                            {
                                result = PropagatorResult.CreateSimpleValue(PropagatorFlags.NoFlags, null);
                            }
                        }
                        else
                        {
                            // get the actual value
                            var relationshipResult = parameterBinding.IsCurrent
                                                         ? translator.RecordConverter.ConvertCurrentValuesToPropagatorResult(
                                                             relationshipEntry, ModifiedPropertiesBehavior.AllModified)
                                                         : translator.RecordConverter.ConvertOriginalValuesToPropagatorResult(
                                                             relationshipEntry, ModifiedPropertiesBehavior.AllModified);
                            var endResult = relationshipResult.GetMemberValue(endMember);
                            var keyProperty = (EdmProperty)parameterBinding.MemberPath.Members[0];
                            result = endResult.GetMemberValue(keyProperty);
                        }
                    }
                    else
                    {
                        // walk through the member path to find the appropriate propagator results
                        result = parameterBinding.IsCurrent ? stateEntry.Current : stateEntry.Original;
                        for (var i = parameterBinding.MemberPath.Members.Count; i > 0;)
                        {
                            --i;
                            var member = parameterBinding.MemberPath.Members[i];
                            result = result.GetMemberValue(member);
                        }
                    }

                    // create DbParameter
                    command.SetParameterValue(result, parameterBinding, translator);
                }
                // Add rows affected parameter
                command.RegisterRowsAffectedParameter(functionMapping.RowsAffectedParameter);
            }
 // <summary>
 // Requires: this translator must be registered to handle the entity set
 // for the given state entry.
 // Translates the given state entry to a command.
 // </summary>
 // <param name="translator"> Parent update translator (global state for the workload) </param>
 // <param name="stateEntry"> State entry to translate. Must belong to the entity/association set handled by this translator </param>
 // <returns> Command corresponding to the given state entry </returns>
 internal abstract FunctionUpdateCommand Translate(
     UpdateTranslator translator,
     ExtractedStateEntry stateEntry);
            internal override FunctionUpdateCommand Translate(
                UpdateTranslator translator,
                ExtractedStateEntry stateEntry)
            {
                if (null == m_mapping)
                {
                    return null;
                }

                var isInsert = EntityState.Added == stateEntry.State;

                EntityUtil.ValidateNecessaryModificationFunctionMapping(
                    isInsert ? m_mapping.InsertFunctionMapping : m_mapping.DeleteFunctionMapping,
                    isInsert ? "Insert" : "Delete",
                    stateEntry.Source, "AssociationSet", m_mapping.AssociationSet.Name);

                // initialize a new command
                var functionMapping = isInsert ? m_mapping.InsertFunctionMapping : m_mapping.DeleteFunctionMapping;
                var command = new FunctionUpdateCommand(
                    functionMapping, translator, new ReadOnlyCollection<IEntityStateEntry>(new[] { stateEntry.Source }.ToList()), stateEntry);

                // extract the relationship values from the state entry
                PropagatorResult recordResult;
                if (isInsert)
                {
                    recordResult = stateEntry.Current;
                }
                else
                {
                    recordResult = stateEntry.Original;
                }

                // bind parameters
                foreach (var 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");

                    var keyProperty = (EdmProperty)parameterBinding.MemberPath.Members[0];
                    var endMember = (AssociationEndMember)parameterBinding.MemberPath.Members[1];

                    // get the end member
                    var endResult = recordResult.GetMemberValue(endMember);
                    var keyResult = endResult.GetMemberValue(keyProperty);

                    command.SetParameterValue(keyResult, parameterBinding, translator);
                }
                // add rows affected output parameter
                command.RegisterRowsAffectedParameter(functionMapping.RowsAffectedParameter);

                return command;
            }
            internal override FunctionUpdateCommand Translate(
                UpdateTranslator translator,
                ExtractedStateEntry stateEntry)
            {
                var mapping = GetFunctionMapping(stateEntry);
                var functionMapping = mapping.Item2;
                var entityKey = stateEntry.Source.EntityKey;

                var stateEntries = new HashSet<IEntityStateEntry>
                    {
                        stateEntry.Source
                    };

                // gather all referenced association ends
                var collocatedEntries =
                    // find all related entries corresponding to collocated association types
                    from end in functionMapping.CollocatedAssociationSetEnds
                    join candidateEntry in translator.GetRelationships(entityKey)
                        on end.CorrespondingAssociationEndMember.DeclaringType equals candidateEntry.EntitySet.ElementType
                    select Tuple.Create(end.CorrespondingAssociationEndMember, candidateEntry);

                var currentReferenceEnds = new Dictionary<AssociationEndMember, IEntityStateEntry>();
                var originalReferenceEnds = new Dictionary<AssociationEndMember, IEntityStateEntry>();

                foreach (var candidate in collocatedEntries)
                {
                    ProcessReferenceCandidate(
                        entityKey, stateEntries, currentReferenceEnds, originalReferenceEnds, candidate.Item1, candidate.Item2);
                }

                // create function object
                FunctionUpdateCommand command;

                // consider the following scenario, we need to loop through all the state entries that is correlated with entity2 and make sure it is not changed.
                // entity1 <-- Independent Association <-- entity2 <-- Fk association <-- entity 3
                //                                           |
                //              entity4 <-- Fk association <--
                if (stateEntries.All(e => e.State == EntityState.Unchanged))
                {
                    // we shouldn't update the entity if it is unchanged, only update when referenced association is changed.
                    // if not, then this will trigger a fake update for principal
                    command = null;
                }
                else
                {
                    command = new FunctionUpdateCommand(functionMapping, translator, new ReadOnlyCollection<IEntityStateEntry>(stateEntries.ToList()), stateEntry);

                    // bind all function parameters
                    BindFunctionParameters(translator, stateEntry, functionMapping, command, currentReferenceEnds, originalReferenceEnds);

                    // interpret all result bindings
                    if (null != functionMapping.ResultBindings)
                    {
                        foreach (var resultBinding in functionMapping.ResultBindings)
                        {
                            var result = stateEntry.Current.GetMemberValue(resultBinding.Property);
                            command.AddResultColumn(translator, resultBinding.ColumnName, result);
                        }
                    }
                }

                return command;
            }
        // Adds a result column binding from a column name (from the result set for the function) to
        // a propagator result (which contains the context necessary to back-propagate the result).
        // If the result is an identifier, binds the 
        internal void AddResultColumn(UpdateTranslator translator, String columnName, PropagatorResult result)
        {
            const int initializeSize = 2; // expect on average less than two result columns per command
            if (null == ResultColumns)
            {
                ResultColumns = new List<KeyValuePair<string, PropagatorResult>>(initializeSize);
            }
            ResultColumns.Add(new KeyValuePair<string, PropagatorResult>(columnName, result));

            var identifier = result.Identifier;
            if (PropagatorResult.NullIdentifier != identifier)
            {
                if (translator.KeyManager.HasPrincipals(identifier))
                {
                    throw new InvalidOperationException(Strings.Update_GeneratedDependent(columnName));
                }

                // register output identifier to enable fix-up and dependency tracking
                AddOutputIdentifier(columnName, identifier);
            }
        }
        /// <summary>
        /// Converts a record to a propagator result
        /// </summary>
        /// <param name="stateEntry">state manager entry containing the record</param>
        /// <param name="isModified">Indicates whether the root element is modified (i.e., whether the type has changed)</param>
        /// <param name="record">Record to convert</param>
        /// <param name="useCurrentValues">Indicates whether we are retrieving current or original values.</param>
        /// <param name="translator">Translator for session context; registers new metadata for the record type if none
        /// exists</param>
        /// <param name="modifiedPropertiesBehavior">Indicates how to determine whether a property is modified.</param>
        /// <returns>Result corresponding to the given record</returns>
        internal static PropagatorResult ExtractResultFromRecord(
            IEntityStateEntry stateEntry, bool isModified, IExtendedDataRecord record,
            bool useCurrentValues, UpdateTranslator translator, ModifiedPropertiesBehavior modifiedPropertiesBehavior)
        {
            var structuralType = (StructuralType)record.DataRecordInfo.RecordType.EdmType;
            var metadata = translator.GetExtractorMetadata(stateEntry.EntitySet, structuralType);
            var key = stateEntry.EntityKey;

            var nestedValues = new PropagatorResult[record.FieldCount];
            for (var ordinal = 0; ordinal < nestedValues.Length; ordinal++)
            {
                nestedValues[ordinal] = metadata.RetrieveMember(
                    stateEntry, record, useCurrentValues, key,
                    ordinal, modifiedPropertiesBehavior);
            }

            return PropagatorResult.CreateStructuralValue(nestedValues, structuralType, isModified);
        }
        // Adds and register a DbParameter to the current command.
        internal void SetParameterValue(
            PropagatorResult result,
            StorageModificationFunctionParameterBinding parameterBinding, UpdateTranslator translator)
        {
            // retrieve DbParameter
            var parameter = _dbCommand.Parameters[parameterBinding.Parameter.Name];
            var parameterType = parameterBinding.Parameter.TypeUsage;
            var parameterValue = translator.KeyManager.GetPrincipalValue(result);
            translator.SetParameterValue(parameter, parameterType, parameterValue);

            // if the parameter corresponds to an identifier (key component), remember this fact in case
            // it's important for dependency ordering (e.g., output the identifier before creating it)
            var identifier = result.Identifier;
            if (PropagatorResult.NullIdentifier != identifier)
            {
                const int initialSize = 2; // expect on average less than two input identifiers per command
                if (null == _inputIdentifiers)
                {
                    _inputIdentifiers = new List<KeyValuePair<int, DbParameter>>(initialSize);
                }
                foreach (var principal in translator.KeyManager.GetPrincipals(identifier))
                {
                    _inputIdentifiers.Add(new KeyValuePair<int, DbParameter>(principal, parameter));
                }
            }
        }
 /// <summary>
 /// Initializes a new converter given a command tree context. Initializes a new record layout cache.
 /// </summary>
 /// <param name="updateTranslator">Sets <see cref="m_updateTranslator" /></param>
 internal RecordConverter(UpdateTranslator updateTranslator)
 {
     m_updateTranslator = updateTranslator;
 }
        internal ExtractorMetadata(EntitySetBase entitySetBase, StructuralType type, UpdateTranslator translator)
        {
            Contract.Requires(entitySetBase != null);
            Contract.Requires(type != null);
            Contract.Requires(translator != null);

            m_type = type;
            m_translator = translator;

            EntityType entityType = null;
            Set<EdmMember> keyMembers;
            Set<EdmMember> foreignKeyMembers;

            switch (type.BuiltInTypeKind)
            {
                case BuiltInTypeKind.RowType:
                    // for row types (which are actually association end key records in disguise), all members
                    // are keys
                    keyMembers = new Set<EdmMember>(((RowType)type).Properties).MakeReadOnly();
                    foreignKeyMembers = Set<EdmMember>.Empty;
                    break;
                case BuiltInTypeKind.EntityType:
                    entityType = (EntityType)type;
                    keyMembers = new Set<EdmMember>(entityType.KeyMembers).MakeReadOnly();
                    foreignKeyMembers = new Set<EdmMember>(
                        ((EntitySet)entitySetBase).ForeignKeyDependents
                            .SelectMany(fk => fk.Item2.ToProperties)).MakeReadOnly();
                    break;
                default:
                    keyMembers = Set<EdmMember>.Empty;
                    foreignKeyMembers = Set<EdmMember>.Empty;
                    break;
            }

            var members = TypeHelpers.GetAllStructuralMembers(type);
            m_memberMap = new MemberInformation[members.Count];
            // for each member, cache expensive to compute metadata information
            for (var ordinal = 0; ordinal < members.Count; ordinal++)
            {
                var member = members[ordinal];
                // figure out flags for this member
                var flags = PropagatorFlags.NoFlags;
                var entityKeyOrdinal = default(int?);

                if (keyMembers.Contains(member))
                {
                    flags |= PropagatorFlags.Key;
                    if (null != entityType)
                    {
                        entityKeyOrdinal = entityType.KeyMembers.IndexOf(member);
                    }
                }
                if (foreignKeyMembers.Contains(member))
                {
                    flags |= PropagatorFlags.ForeignKey;
                }

                if (MetadataHelper.GetConcurrencyMode(member)
                    == ConcurrencyMode.Fixed)
                {
                    flags |= PropagatorFlags.ConcurrencyValue;
                }

                // figure out whether this member is mapped to any server generated
                // columns in the store
                var isServerGenerated = m_translator.ViewLoader.IsServerGen(entitySetBase, m_translator.MetadataWorkspace, member);

                // figure out whether member nullability is used as a condition in mapping
                var isNullConditionMember = m_translator.ViewLoader.IsNullConditionMember(
                    entitySetBase, m_translator.MetadataWorkspace, member);

                // add information about this member
                m_memberMap[ordinal] = new MemberInformation(
                    ordinal, entityKeyOrdinal, flags, member, isServerGenerated, isNullConditionMember);
            }
        }
 private SourceInterpreter(UpdateTranslator translator, EntitySet sourceTable)
 {
     m_stateEntries = new List<IEntityStateEntry>();
     m_translator = translator;
     m_sourceTable = sourceTable;
 }
 /// <summary>
 ///     Initialize an update compiler.
 /// </summary>
 /// <param name="translator"> Update context. </param>
 internal UpdateCompiler(UpdateTranslator translator)
 {
     m_translator = translator;
 }
        protected virtual long GetRowsAffected(long rowsAffected, UpdateTranslator translator)
        {
            // if an explicit rows affected parameter exists, use this value instead
            if (null != _rowsAffectedParameter)
            {
                // by design, negative row counts indicate failure iff. an explicit rows
                // affected parameter is used
                if (DBNull.Value.Equals(_rowsAffectedParameter.Value))
                {
                    rowsAffected = 0;
                }
                else
                {
                    try
                    {
                        rowsAffected = Convert.ToInt64(_rowsAffectedParameter.Value, CultureInfo.InvariantCulture);
                    }
                    catch (Exception e)
                    {
                        if (e.RequiresContext())
                        {
                            // wrap the exception
                            throw new UpdateException(
                                Strings.Update_UnableToConvertRowsAffectedParameter(
                                    _rowsAffectedParameter.ParameterName, typeof(Int64).FullName),
                                e, GetStateEntries(translator).Cast<ObjectStateEntry>().Distinct());
                        }
                        throw;
                    }
                }
            }

            return rowsAffected;
        }
 private int GetColumnOrdinal(UpdateTranslator translator, DbDataReader reader, string columnName)
 {
     int columnOrdinal;
     try
     {
         columnOrdinal = reader.GetOrdinal(columnName);
     }
     catch (IndexOutOfRangeException)
     {
         throw new UpdateException(
             Strings.Update_MissingResultColumn(columnName), null, GetStateEntries(translator).Cast<ObjectStateEntry>().Distinct());
     }
     return columnOrdinal;
 }
        internal override IList<IEntityStateEntry> GetStateEntries(UpdateTranslator translator)
        {
            var stateEntries = new List<IEntityStateEntry>(2);
            if (null != OriginalValues)
            {
                foreach (var stateEntry in SourceInterpreter.GetAllStateEntries(
                    OriginalValues, translator, Table))
                {
                    stateEntries.Add(stateEntry);
                }
            }

            if (null != CurrentValues)
            {
                foreach (var stateEntry in SourceInterpreter.GetAllStateEntries(
                    CurrentValues, translator, Table))
                {
                    stateEntries.Add(stateEntry);
                }
            }
            return stateEntries;
        }
 /// <summary>
 /// Gets state entries contributing to this function. Supports error reporting.
 /// </summary>
 internal override IList<IEntityStateEntry> GetStateEntries(UpdateTranslator translator)
 {
     return _stateEntries;
 }