SQLite Transaction抛出异常,我无法弄清楚

时间:2013-08-31 04:18:05

标签: c# sqlite

    public void test2(String[] users)
    {
        Stopwatch stopwatch = new Stopwatch();
        stopwatch.Start();
        using (var myTransaction = myDB.BeginTransaction())
        {
            using (cmd = myDB.CreateCommand())
            {
                cmd.Transaction = myTransaction;
                cmd.CommandText = "UPDATE myTable SET counter = counter + 1 WHERE user = @user";
                cmd.Parameters.AddWithValue("@user", "");
                foreach (string person in users)
                {
                    cmd.Parameters["@user"].Value = person;
                    cmd.ExecuteNonQuery();
                } 
            }
            myTransaction.Commit();
            stopwatch.Stop();
            Console.WriteLine("Updating existing users took: " + stopwatch.Elapsed);
        }
    }

我有一个时间想到这一个的野兽。我查看了大量的c#事务示例,除了拥有foreach循环外,我的代码看起来非常类似于所有这些代码。但是我在单个事务中看到过多个ExeCuteNonQuery,所以我不知道问题是什么。有什么帮助吗?

编辑:猜猜我应该解释一下这个问题:P

获得:

"System.ObjectDisposedException: Cannot access a disposed object. Object name: 'SQLiteCommand'."

cmd.Parameters["@user"].Value = person;行。

2 个答案:

答案 0 :(得分:4)

我的猜测是命令在执行后被释放。尝试将foreach循环放在外面:

foreach (string person in users)
{
    using (cmd = myDB.CreateCommand())
    {
        cmd.Transaction = myTransaction;
        cmd.CommandText = "UPDATE myTable SET counter = counter + 1 WHERE user = @user";
        cmd.Parameters.AddWithValue("@user", person);
        cmd.ExecuteNonQuery();
    } 
}

答案 1 :(得分:1)

看起来变量cmd是一个字段。这可以解释为什么命令可以在foreach循环期间处理。如果运行test2而另一个测试并行运行,那么另一个测试可以处理cmd字段中的任何内容。要解决此问题,请从类中删除cmd并将其转换为方法的局部变量。例如,使用(var cmd = myDB.CreateCommand())