예제 #1
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);
        }
        // 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);
        }
        // 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;
        }