SQlite 连接在执行前自行关闭

SQlite connection closes itself before execution

我遇到了一个奇怪的问题,我似乎找不到答案...

我有一段代码使用事务和参数将数据插入到 SQlite 数据库中。它从传递的对象 List<T> 列表中获取值。总共有74个参数...我的代码是这样的

            dbConnection.Open();

            
            using (SqliteTransaction transaction = dbConnection.BeginTransaction())
            {
                foreach (CardScryfall _card in _cards)
                {
                    SqliteCommand com = dbConnection.CreateCommand();
                    com.CommandText = sql;
                    com.Parameters.Add("@dbid", SqliteType.Integer); //Mandatory
                                                                     //Assign values to Parameters
                    com.Parameters[0].Value = GetNextDBID();
                    //Assign card properties to parameters
                    com.Parameters.Add("@objectName", SqliteType.Text);
                    com.Parameters[com.Parameters.IndexOf("@objectName")].Value = _card.objectName;
                    
                    //Next 72 parameters are created the same way.
                    

                    //Replace NULL with DBNull.Value
                    foreach (SqliteParameter par in com.Parameters)
                    {
                        if (par.Value == null)
                        {
                            par.Value = DBNull.Value;
                        }
                    }

                    //Execute query
                    
                    com.Prepare();
                    com.ExecuteNonQuery();
                    transaction.Commit();
                    com.Dispose();
                    
                }
            }
            dbConnection.Close();

现在...当我删除 using transaction 部分时,代码工作正常,但速度非常慢... 所以我想把它打包成一个事务来提高性能。

现在的问题是在添加参数的某个地方(每次我单步执行代码时都不同)dbconnection.State 从打开变为关闭,所以当代码第一次到达 com.Prepare() 时插入,我收到连接已关闭的错误...我有 10k+ 条记录要插入

我尝试设置 dbConnection.DefaultTimeout = 0 但没有帮助...

你能帮忙吗???

谢谢

更新:

我发现了我的问题... 函数 GetNextDBID() 正在检索打开和关闭 DBconnection 的最后一个 recordID...所以我更改了代码,现在它工作正常

无需在循环中创建命令。您应该创建一次,然后只为参数分配新值。

同样,您不需要在循环的每次迭代中都提交事务。最后做一次。

using (var dbConnection = new SqliteConnection(_connectionString))
{
    dbConnection.Open();

    using (SqliteTransaction transaction = dbConnection.BeginTransaction())
    using (SqliteCommand com = dbConnection.CreateCommand())
    {
        com.CommandText = sql;

        com.Parameters.Add("@dbid", SqliteType.Integer);
        com.Parameters.Add("@objectName", SqliteType.Text);
        // ...

        com.Prepare();

        foreach (CardScryfall _card in _cards)
        {
            com.Parameters["@dbid"].Value = GetNextDBID();
            com.Parameters["@objectName"].Value = (object)_card.objectName ?? DBNull.Value;
            // ...

            _ = com.ExecuteNonQuery();
        }
        transaction.Commit();
    }
}