// Determines key values for a list of changes. Side effect: populates <see cref="keys" /> which
        // includes an entry for every key involved in a change.
        private Dictionary <CompositeKey, PropagatorResult> ProcessKeys(
            UpdateCompiler compiler, List <PropagatorResult> changes, Set <CompositeKey> keys)
        {
            var map = new Dictionary <CompositeKey, PropagatorResult>(
                compiler.m_translator.KeyComparer);

            foreach (var change in changes)
            {
                // Reassign change to row since we cannot modify iteration variable
                var row = change;

                var key = new CompositeKey(GetKeyConstants(row));

                // Make sure we aren't inserting another row with the same key
                PropagatorResult other;
                if (map.TryGetValue(key, out other))
                {
                    DiagnoseKeyCollision(compiler, change, key, other);
                }

                map.Add(key, row);
                keys.Add(key);
            }

            return(map);
        }
예제 #2
0
        private DbExpression BuildPredicate(
            DbExpressionBinding target,
            PropagatorResult referenceRow,
            PropagatorResult current,
            TableChangeProcessor processor,
            ref bool rowMustBeTouched)
        {
            Dictionary <EdmProperty, PropagatorResult> dictionary = new Dictionary <EdmProperty, PropagatorResult>();
            int ordinal = 0;

            foreach (EdmProperty property in processor.Table.ElementType.Properties)
            {
                PropagatorResult memberValue = referenceRow.GetMemberValue(ordinal);
                PropagatorResult input       = current == null ? (PropagatorResult)null : current.GetMemberValue(ordinal);
                if (!rowMustBeTouched && (UpdateCompiler.HasFlag(memberValue, PropagatorFlags.ConcurrencyValue) || UpdateCompiler.HasFlag(input, PropagatorFlags.ConcurrencyValue)))
                {
                    rowMustBeTouched = true;
                }
                if (!dictionary.ContainsKey(property) && (UpdateCompiler.HasFlag(memberValue, PropagatorFlags.ConcurrencyValue | PropagatorFlags.Key) || UpdateCompiler.HasFlag(input, PropagatorFlags.ConcurrencyValue | PropagatorFlags.Key)))
                {
                    dictionary.Add(property, memberValue);
                }
                ++ordinal;
            }
            DbExpression left = (DbExpression)null;

            foreach (KeyValuePair <EdmProperty, PropagatorResult> keyValuePair in dictionary)
            {
                DbExpression equalityExpression = this.GenerateEqualityExpression(target, keyValuePair.Key, keyValuePair.Value);
                left = left != null ? (DbExpression)left.And(equalityExpression) : equalityExpression;
            }
            return(left);
        }
예제 #3
0
        internal UpdateCommand BuildDeleteCommand(
            PropagatorResult oldRow,
            TableChangeProcessor processor)
        {
            bool rowMustBeTouched                 = true;
            DbExpressionBinding target            = UpdateCompiler.GetTarget(processor);
            DbExpression        predicate         = this.BuildPredicate(target, oldRow, (PropagatorResult)null, processor, ref rowMustBeTouched);
            DbDeleteCommandTree deleteCommandTree = new DbDeleteCommandTree(this.m_translator.MetadataWorkspace, DataSpace.SSpace, target, predicate);

            return((UpdateCommand) new DynamicUpdateCommand(processor, this.m_translator, ModificationOperator.Delete, oldRow, (PropagatorResult)null, (DbModificationCommandTree)deleteCommandTree, (Dictionary <int, string>)null));
        }
예제 #4
0
        internal List <UpdateCommand> CompileCommands(
            ChangeNode changeNode,
            UpdateCompiler compiler)
        {
            Set <CompositeKey> keys = new Set <CompositeKey>(compiler.m_translator.KeyComparer);
            Dictionary <CompositeKey, PropagatorResult> dictionary1 = this.ProcessKeys(compiler, changeNode.Deleted, keys);
            Dictionary <CompositeKey, PropagatorResult> dictionary2 = this.ProcessKeys(compiler, changeNode.Inserted, keys);
            List <UpdateCommand> updateCommandList = new List <UpdateCommand>(dictionary1.Count + dictionary2.Count);

            foreach (CompositeKey key in keys)
            {
                PropagatorResult propagatorResult1;
                bool             flag1 = dictionary1.TryGetValue(key, out propagatorResult1);
                PropagatorResult propagatorResult2;
                bool             flag2 = dictionary2.TryGetValue(key, out propagatorResult2);
                try
                {
                    if (!flag1)
                    {
                        updateCommandList.Add(compiler.BuildInsertCommand(propagatorResult2, this));
                    }
                    else if (!flag2)
                    {
                        updateCommandList.Add(compiler.BuildDeleteCommand(propagatorResult1, this));
                    }
                    else
                    {
                        UpdateCommand updateCommand = compiler.BuildUpdateCommand(propagatorResult1, propagatorResult2, this);
                        if (updateCommand != null)
                        {
                            updateCommandList.Add(updateCommand);
                        }
                    }
                }
                catch (Exception ex)
                {
                    if (ex.RequiresContext())
                    {
                        List <IEntityStateEntry> source = new List <IEntityStateEntry>();
                        if (propagatorResult1 != null)
                        {
                            source.AddRange((IEnumerable <IEntityStateEntry>)SourceInterpreter.GetAllStateEntries(propagatorResult1, compiler.m_translator, this.m_table));
                        }
                        if (propagatorResult2 != null)
                        {
                            source.AddRange((IEnumerable <IEntityStateEntry>)SourceInterpreter.GetAllStateEntries(propagatorResult2, compiler.m_translator, this.m_table));
                        }
                        throw new UpdateException(Strings.Update_GeneralExecutionException, ex, source.Cast <ObjectStateEntry>().Distinct <ObjectStateEntry>());
                    }
                    throw;
                }
            }
            return(updateCommandList);
        }
예제 #5
0
        private DbExpression GenerateEqualityExpression(
            DbExpressionBinding target,
            EdmProperty property,
            PropagatorResult value)
        {
            DbExpression propertyExpression = UpdateCompiler.GeneratePropertyExpression(target, property);
            DbExpression valueExpression    = this.GenerateValueExpression(property, value);

            if (valueExpression.ExpressionKind == DbExpressionKind.Null)
            {
                return((DbExpression)propertyExpression.IsNull());
            }
            return((DbExpression)propertyExpression.Equal(valueExpression));
        }
예제 #6
0
        private void DiagnoseKeyCollision(
            UpdateCompiler compiler,
            PropagatorResult change,
            CompositeKey key,
            PropagatorResult other)
        {
            KeyManager   keyManager   = compiler.m_translator.KeyManager;
            CompositeKey compositeKey = new CompositeKey(this.GetKeyConstants(other));
            bool         flag         = true;

            for (int index = 0; flag && index < key.KeyComponents.Length; ++index)
            {
                int identifier1 = key.KeyComponents[index].Identifier;
                int identifier2 = compositeKey.KeyComponents[index].Identifier;
                if (!keyManager.GetPrincipals(identifier1).Intersect <int>(keyManager.GetPrincipals(identifier2)).Any <int>())
                {
                    flag = false;
                }
            }
            if (flag)
            {
                throw new UpdateException(Strings.Update_DuplicateKeys, (Exception)null, SourceInterpreter.GetAllStateEntries(change, compiler.m_translator, this.m_table).Concat <IEntityStateEntry>((IEnumerable <IEntityStateEntry>)SourceInterpreter.GetAllStateEntries(other, compiler.m_translator, this.m_table)).Cast <ObjectStateEntry>().Distinct <ObjectStateEntry>());
            }
            HashSet <IEntityStateEntry> source = (HashSet <IEntityStateEntry>)null;

            foreach (PropagatorResult propagatorResult in ((IEnumerable <PropagatorResult>)key.KeyComponents).Concat <PropagatorResult>((IEnumerable <PropagatorResult>)compositeKey.KeyComponents))
            {
                HashSet <IEntityStateEntry> entityStateEntrySet = new HashSet <IEntityStateEntry>();
                foreach (int dependent in keyManager.GetDependents(propagatorResult.Identifier))
                {
                    PropagatorResult owner;
                    if (keyManager.TryGetIdentifierOwner(dependent, out owner) && owner.StateEntry != null)
                    {
                        entityStateEntrySet.Add(owner.StateEntry);
                    }
                }
                if (source == null)
                {
                    source = new HashSet <IEntityStateEntry>((IEnumerable <IEntityStateEntry>)entityStateEntrySet);
                }
                else
                {
                    source.IntersectWith((IEnumerable <IEntityStateEntry>)entityStateEntrySet);
                }
            }
            throw new UpdateException(Strings.Update_GeneralExecutionException, (Exception) new ConstraintException(Strings.Update_ReferentialConstraintIntegrityViolation), source.Cast <ObjectStateEntry>().Distinct <ObjectStateEntry>());
        }
예제 #7
0
        internal UpdateCommand BuildInsertCommand(
            PropagatorResult newRow,
            TableChangeProcessor processor)
        {
            DbExpressionBinding target = UpdateCompiler.GetTarget(processor);
            bool rowMustBeTouched      = true;
            List <DbModificationClause> modificationClauseList = new List <DbModificationClause>();
            Dictionary <int, string>    outputIdentifiers;
            DbExpression returning;

            foreach (DbModificationClause buildSetClause in this.BuildSetClauses(target, newRow, (PropagatorResult)null, processor, true, out outputIdentifiers, out returning, ref rowMustBeTouched))
            {
                modificationClauseList.Add(buildSetClause);
            }
            DbInsertCommandTree insertCommandTree = new DbInsertCommandTree(this.m_translator.MetadataWorkspace, DataSpace.SSpace, target, new ReadOnlyCollection <DbModificationClause>((IList <DbModificationClause>)modificationClauseList), returning);

            return((UpdateCommand) new DynamicUpdateCommand(processor, this.m_translator, ModificationOperator.Insert, (PropagatorResult)null, newRow, (DbModificationCommandTree)insertCommandTree, outputIdentifiers));
        }
예제 #8
0
        private Dictionary <CompositeKey, PropagatorResult> ProcessKeys(
            UpdateCompiler compiler,
            List <PropagatorResult> changes,
            Set <CompositeKey> keys)
        {
            Dictionary <CompositeKey, PropagatorResult> dictionary = new Dictionary <CompositeKey, PropagatorResult>(compiler.m_translator.KeyComparer);

            foreach (PropagatorResult change in changes)
            {
                PropagatorResult row          = change;
                CompositeKey     compositeKey = new CompositeKey(this.GetKeyConstants(row));
                PropagatorResult other;
                if (dictionary.TryGetValue(compositeKey, out other))
                {
                    this.DiagnoseKeyCollision(compiler, change, compositeKey, other);
                }
                dictionary.Add(compositeKey, row);
                keys.Add(compositeKey);
            }
            return(dictionary);
        }
예제 #9
0
        internal UpdateCommand BuildUpdateCommand(
            PropagatorResult oldRow,
            PropagatorResult newRow,
            TableChangeProcessor processor)
        {
            bool rowMustBeTouched = false;
            DbExpressionBinding         target = UpdateCompiler.GetTarget(processor);
            List <DbModificationClause> modificationClauseList = new List <DbModificationClause>();
            Dictionary <int, string>    outputIdentifiers;
            DbExpression returning;

            foreach (DbModificationClause buildSetClause in this.BuildSetClauses(target, newRow, oldRow, processor, false, out outputIdentifiers, out returning, ref rowMustBeTouched))
            {
                modificationClauseList.Add(buildSetClause);
            }
            DbExpression predicate = this.BuildPredicate(target, oldRow, newRow, processor, ref rowMustBeTouched);

            if (modificationClauseList.Count == 0)
            {
                if (rowMustBeTouched)
                {
                    List <IEntityStateEntry> source = new List <IEntityStateEntry>();
                    source.AddRange((IEnumerable <IEntityStateEntry>)SourceInterpreter.GetAllStateEntries(oldRow, this.m_translator, processor.Table));
                    source.AddRange((IEnumerable <IEntityStateEntry>)SourceInterpreter.GetAllStateEntries(newRow, this.m_translator, processor.Table));
                    if (source.All <IEntityStateEntry>((Func <IEntityStateEntry, bool>)(it => it.State == EntityState.Unchanged)))
                    {
                        rowMustBeTouched = false;
                    }
                }
                if (!rowMustBeTouched)
                {
                    return((UpdateCommand)null);
                }
            }
            DbUpdateCommandTree updateCommandTree = new DbUpdateCommandTree(this.m_translator.MetadataWorkspace, DataSpace.SSpace, target, predicate, new ReadOnlyCollection <DbModificationClause>((IList <DbModificationClause>)modificationClauseList), returning);

            return((UpdateCommand) new DynamicUpdateCommand(processor, this.m_translator, ModificationOperator.Update, oldRow, newRow, (DbModificationCommandTree)updateCommandTree, outputIdentifiers));
        }
        private void DiagnoseKeyCollision(UpdateCompiler compiler, PropagatorResult change, CompositeKey key, PropagatorResult other)
        {
            var keyManager = compiler.m_translator.KeyManager;
            var otherKey   = new CompositeKey(GetKeyConstants(other));

            // determine if the conflict is due to shared principal key values
            var sharedPrincipal = true;

            for (var i = 0; sharedPrincipal && i < key.KeyComponents.Length; i++)
            {
                var identifier1 = key.KeyComponents[i].Identifier;
                var identifier2 = otherKey.KeyComponents[i].Identifier;

                if (!keyManager.GetPrincipals(identifier1).Intersect(keyManager.GetPrincipals(identifier2)).Any())
                {
                    sharedPrincipal = false;
                }
            }

            if (sharedPrincipal)
            {
                // if the duplication is due to shared principals, there is a duplicate key exception
                var stateEntries = SourceInterpreter.GetAllStateEntries(change, compiler.m_translator, m_table)
                                   .Concat(SourceInterpreter.GetAllStateEntries(other, compiler.m_translator, m_table));
                throw new UpdateException(Strings.Update_DuplicateKeys, null, stateEntries.Cast <ObjectStateEntry>().Distinct());
            }
            else
            {
                // if there are no shared principals, it implies that common dependents are the problem
                HashSet <IEntityStateEntry> commonDependents = null;
                foreach (var keyValue in key.KeyComponents.Concat(otherKey.KeyComponents))
                {
                    var dependents = new HashSet <IEntityStateEntry>();
                    foreach (var dependentId in keyManager.GetDependents(keyValue.Identifier))
                    {
                        PropagatorResult dependentResult;
                        if (keyManager.TryGetIdentifierOwner(dependentId, out dependentResult)
                            &&
                            null != dependentResult.StateEntry)
                        {
                            dependents.Add(dependentResult.StateEntry);
                        }
                    }
                    if (null == commonDependents)
                    {
                        commonDependents = new HashSet <IEntityStateEntry>(dependents);
                    }
                    else
                    {
                        commonDependents.IntersectWith(dependents);
                    }
                }

                // to ensure the exception shape is consistent with constraint violations discovered while processing
                // commands (a more conventional scenario in which different tables are contributing principal values)
                // wrap a DataConstraintException in an UpdateException
                throw new UpdateException(
                          Strings.Update_GeneralExecutionException,
                          new ConstraintException(Strings.Update_ReferentialConstraintIntegrityViolation),
                          commonDependents.Cast <ObjectStateEntry>().Distinct());
            }
        }
        // Processes all insert and delete requests in the table's <see cref="ChangeNode" />. Inserts
        // and deletes with the same key are merged into updates.
        internal List <UpdateCommand> CompileCommands(ChangeNode changeNode, UpdateCompiler compiler)
        {
            var keys = new Set <CompositeKey>(compiler.m_translator.KeyComparer);

            // Retrieve all delete results (original values) and insert results (current values) while
            // populating a set of all row keys. The set contains a single key per row.
            var deleteResults = ProcessKeys(compiler, changeNode.Deleted, keys);
            var insertResults = ProcessKeys(compiler, changeNode.Inserted, keys);

            var commands = new List <UpdateCommand>(deleteResults.Count + insertResults.Count);

            // Examine each row key to see if the row is being deleted, inserted or updated
            foreach (var key in keys)
            {
                PropagatorResult deleteResult;
                PropagatorResult insertResult;

                var hasDelete = deleteResults.TryGetValue(key, out deleteResult);
                var hasInsert = insertResults.TryGetValue(key, out insertResult);

                Debug.Assert(
                    hasDelete || hasInsert, "(update/TableChangeProcessor) m_keys must not contain a value " +
                    "if there is no corresponding insert or delete");

                try
                {
                    if (!hasDelete)
                    {
                        // this is an insert
                        commands.Add(compiler.BuildInsertCommand(insertResult, this));
                    }
                    else if (!hasInsert)
                    {
                        // this is a delete
                        commands.Add(compiler.BuildDeleteCommand(deleteResult, this));
                    }
                    else
                    {
                        // this is an update because it has both a delete result and an insert result
                        var updateCommand = compiler.BuildUpdateCommand(deleteResult, insertResult, this);
                        if (null != updateCommand)
                        {
                            // if null is returned, it means it is a no-op update
                            commands.Add(updateCommand);
                        }
                    }
                }
                catch (Exception e)
                {
                    if (e.RequiresContext())
                    {
                        // collect state entries in scope for the current compilation
                        var stateEntries = new List <IEntityStateEntry>();
                        if (null != deleteResult)
                        {
                            stateEntries.AddRange(
                                SourceInterpreter.GetAllStateEntries(
                                    deleteResult, compiler.m_translator, m_table));
                        }
                        if (null != insertResult)
                        {
                            stateEntries.AddRange(
                                SourceInterpreter.GetAllStateEntries(
                                    insertResult, compiler.m_translator, m_table));
                        }

                        throw new UpdateException(
                                  Strings.Update_GeneralExecutionException, e, stateEntries.Cast <ObjectStateEntry>().Distinct());
                    }
                    throw;
                }
            }

            return(commands);
        }
        private void DiagnoseKeyCollision(UpdateCompiler compiler, PropagatorResult change, CompositeKey key, PropagatorResult other)
        {
            var keyManager = compiler.m_translator.KeyManager;
            var otherKey = new CompositeKey(GetKeyConstants(other));

            // determine if the conflict is due to shared principal key values
            var sharedPrincipal = true;
            for (var i = 0; sharedPrincipal && i < key.KeyComponents.Length; i++)
            {
                var identifier1 = key.KeyComponents[i].Identifier;
                var identifier2 = otherKey.KeyComponents[i].Identifier;

                if (!keyManager.GetPrincipals(identifier1).Intersect(keyManager.GetPrincipals(identifier2)).Any())
                {
                    sharedPrincipal = false;
                }
            }

            if (sharedPrincipal)
            {
                // if the duplication is due to shared principals, there is a duplicate key exception
                var stateEntries = SourceInterpreter.GetAllStateEntries(change, compiler.m_translator, m_table)
                                                    .Concat(SourceInterpreter.GetAllStateEntries(other, compiler.m_translator, m_table));
                throw new UpdateException(Strings.Update_DuplicateKeys, null, stateEntries.Cast<ObjectStateEntry>().Distinct());
            }
            else
            {
                // if there are no shared principals, it implies that common dependents are the problem
                HashSet<IEntityStateEntry> commonDependents = null;
                foreach (var keyValue in key.KeyComponents.Concat(otherKey.KeyComponents))
                {
                    var dependents = new HashSet<IEntityStateEntry>();
                    foreach (var dependentId in keyManager.GetDependents(keyValue.Identifier))
                    {
                        PropagatorResult dependentResult;
                        if (keyManager.TryGetIdentifierOwner(dependentId, out dependentResult)
                            &&
                            null != dependentResult.StateEntry)
                        {
                            dependents.Add(dependentResult.StateEntry);
                        }
                    }
                    if (null == commonDependents)
                    {
                        commonDependents = new HashSet<IEntityStateEntry>(dependents);
                    }
                    else
                    {
                        commonDependents.IntersectWith(dependents);
                    }
                }

                // to ensure the exception shape is consistent with constraint violations discovered while processing
                // commands (a more conventional scenario in which different tables are contributing principal values)
                // wrap a DataConstraintException in an UpdateException
                throw new UpdateException(
                    Strings.Update_GeneralExecutionException,
                    new ConstraintException(Strings.Update_ReferentialConstraintIntegrityViolation),
                    commonDependents.Cast<ObjectStateEntry>().Distinct());
            }
        }
        // Determines key values for a list of changes. Side effect: populates <see cref="keys" /> which
        // includes an entry for every key involved in a change.
        private Dictionary<CompositeKey, PropagatorResult> ProcessKeys(
            UpdateCompiler compiler, List<PropagatorResult> changes, Set<CompositeKey> keys)
        {
            var map = new Dictionary<CompositeKey, PropagatorResult>(
                compiler.m_translator.KeyComparer);

            foreach (var change in changes)
            {
                // Reassign change to row since we cannot modify iteration variable
                var row = change;

                var key = new CompositeKey(GetKeyConstants(row));

                // Make sure we aren't inserting another row with the same key
                PropagatorResult other;
                if (map.TryGetValue(key, out other))
                {
                    DiagnoseKeyCollision(compiler, change, key, other);
                }

                map.Add(key, row);
                keys.Add(key);
            }

            return map;
        }
        // Processes all insert and delete requests in the table's <see cref="ChangeNode" />. Inserts
        // and deletes with the same key are merged into updates.
        internal List<UpdateCommand> CompileCommands(ChangeNode changeNode, UpdateCompiler compiler)
        {
            var keys = new Set<CompositeKey>(compiler.m_translator.KeyComparer);

            // Retrieve all delete results (original values) and insert results (current values) while
            // populating a set of all row keys. The set contains a single key per row.
            var deleteResults = ProcessKeys(compiler, changeNode.Deleted, keys);
            var insertResults = ProcessKeys(compiler, changeNode.Inserted, keys);

            var commands = new List<UpdateCommand>(deleteResults.Count + insertResults.Count);

            // Examine each row key to see if the row is being deleted, inserted or updated
            foreach (var key in keys)
            {
                PropagatorResult deleteResult;
                PropagatorResult insertResult;

                var hasDelete = deleteResults.TryGetValue(key, out deleteResult);
                var hasInsert = insertResults.TryGetValue(key, out insertResult);

                Debug.Assert(
                    hasDelete || hasInsert, "(update/TableChangeProcessor) m_keys must not contain a value " +
                                            "if there is no corresponding insert or delete");

                try
                {
                    if (!hasDelete)
                    {
                        // this is an insert
                        commands.Add(compiler.BuildInsertCommand(insertResult, this));
                    }
                    else if (!hasInsert)
                    {
                        // this is a delete
                        commands.Add(compiler.BuildDeleteCommand(deleteResult, this));
                    }
                    else
                    {
                        // this is an update because it has both a delete result and an insert result
                        var updateCommand = compiler.BuildUpdateCommand(deleteResult, insertResult, this);
                        if (null != updateCommand)
                        {
                            // if null is returned, it means it is a no-op update
                            commands.Add(updateCommand);
                        }
                    }
                }
                catch (Exception e)
                {
                    if (e.RequiresContext())
                    {
                        // collect state entries in scope for the current compilation
                        var stateEntries = new List<IEntityStateEntry>();
                        if (null != deleteResult)
                        {
                            stateEntries.AddRange(
                                SourceInterpreter.GetAllStateEntries(
                                    deleteResult, compiler.m_translator, m_table));
                        }
                        if (null != insertResult)
                        {
                            stateEntries.AddRange(
                                SourceInterpreter.GetAllStateEntries(
                                    insertResult, compiler.m_translator, m_table));
                        }

                        throw new UpdateException(
                            Strings.Update_GeneralExecutionException, e, stateEntries.Cast<ObjectStateEntry>().Distinct());
                    }
                    throw;
                }
            }

            return commands;
        }
예제 #15
0
        private IEnumerable <DbModificationClause> BuildSetClauses(
            DbExpressionBinding target,
            PropagatorResult row,
            PropagatorResult originalRow,
            TableChangeProcessor processor,
            bool insertMode,
            out Dictionary <int, string> outputIdentifiers,
            out DbExpression returning,
            ref bool rowMustBeTouched)
        {
            Dictionary <EdmProperty, PropagatorResult>  dictionary       = new Dictionary <EdmProperty, PropagatorResult>();
            List <KeyValuePair <string, DbExpression> > keyValuePairList = new List <KeyValuePair <string, DbExpression> >();

            outputIdentifiers = new Dictionary <int, string>();
            PropagatorFlags propagatorFlags1 = insertMode ? PropagatorFlags.NoFlags : PropagatorFlags.Preserve | PropagatorFlags.Unknown;

            for (int index1 = 0; index1 < processor.Table.ElementType.Properties.Count; ++index1)
            {
                EdmProperty      property = processor.Table.ElementType.Properties[index1];
                PropagatorResult result   = row.GetMemberValue(index1);
                if (-1 != result.Identifier)
                {
                    result = result.ReplicateResultWithNewValue(this.m_translator.KeyManager.GetPrincipalValue(result));
                }
                bool flag1 = false;
                bool flag2 = false;
                for (int index2 = 0; index2 < processor.KeyOrdinals.Length; ++index2)
                {
                    if (processor.KeyOrdinals[index2] == index1)
                    {
                        flag2 = true;
                        break;
                    }
                }
                PropagatorFlags propagatorFlags2 = PropagatorFlags.NoFlags;
                if (!insertMode && flag2)
                {
                    flag1 = true;
                }
                else
                {
                    propagatorFlags2 |= result.PropagatorFlags;
                }
                StoreGeneratedPattern generatedPattern = MetadataHelper.GetStoreGeneratedPattern((EdmMember)property);
                bool flag3 = generatedPattern == StoreGeneratedPattern.Computed || insertMode && generatedPattern == StoreGeneratedPattern.Identity;
                if (flag3)
                {
                    DbPropertyExpression propertyExpression = target.Variable.Property(property);
                    keyValuePairList.Add(new KeyValuePair <string, DbExpression>(property.Name, (DbExpression)propertyExpression));
                    int identifier = result.Identifier;
                    if (-1 != identifier)
                    {
                        if (this.m_translator.KeyManager.HasPrincipals(identifier))
                        {
                            throw new InvalidOperationException(Strings.Update_GeneratedDependent((object)property.Name));
                        }
                        outputIdentifiers.Add(identifier, property.Name);
                        if (generatedPattern != StoreGeneratedPattern.Identity && processor.IsKeyProperty(index1))
                        {
                            throw new NotSupportedException(Strings.Update_NotSupportedComputedKeyColumn((object)"StoreGeneratedPattern", (object)"Computed", (object)"Identity", (object)property.Name, (object)property.DeclaringType.FullName));
                        }
                    }
                }
                if ((propagatorFlags2 & propagatorFlags1) != PropagatorFlags.NoFlags)
                {
                    flag1 = true;
                }
                else if (flag3)
                {
                    flag1            = true;
                    rowMustBeTouched = true;
                }
                if (!flag1 && !insertMode && generatedPattern == StoreGeneratedPattern.Identity)
                {
                    PropagatorResult memberValue = originalRow.GetMemberValue(index1);
                    if (!ByValueEqualityComparer.Default.Equals(memberValue.GetSimpleValue(), result.GetSimpleValue()))
                    {
                        throw new InvalidOperationException(Strings.Update_ModifyingIdentityColumn((object)"Identity", (object)property.Name, (object)property.DeclaringType.FullName));
                    }
                    flag1 = true;
                }
                if (!flag1)
                {
                    dictionary.Add(property, result);
                }
            }
            returning = 0 >= keyValuePairList.Count ? (DbExpression)null : (DbExpression)DbExpressionBuilder.NewRow((IEnumerable <KeyValuePair <string, DbExpression> >)keyValuePairList);
            List <DbModificationClause> modificationClauseList = new List <DbModificationClause>(dictionary.Count);

            foreach (KeyValuePair <EdmProperty, PropagatorResult> keyValuePair in dictionary)
            {
                EdmProperty key = keyValuePair.Key;
                modificationClauseList.Add((DbModificationClause) new DbSetClause(UpdateCompiler.GeneratePropertyExpression(target, keyValuePair.Key), this.GenerateValueExpression(keyValuePair.Key, keyValuePair.Value)));
            }
            return((IEnumerable <DbModificationClause>)modificationClauseList);
        }