【问题标题】:Finalise SQLite 3 statement完成 SQLite 3 语句
【发布时间】:2012-08-15 21:55:30
【问题描述】:

我正在使用 Windows 8 发布预览版和 C#(VS 2012) 开发 Metro 应用程序,我是 SQLite 新手,我在我的应用程序中集成了 SQLite 3.7.13,它运行良好,请查看下面的代码

var dbPath = Path.Combine(Windows.Storage.ApplicationData.Current.LocalFolder.Path, "Test.db");
using (var db = new SQLite.SQLiteConnection(dbPath))
{                       
    var data = db.Table<tablename>().Where(tablename => tablename.uploaded_bool == false && tablename.Sid == 26);
    try
    {
        int iDataCount = data.Count();
        int id;                        
        if (iDataCount > 0)
        {                  
            for (int i = 0; i < iDataCount; i++)
            {
                Elements = data.ElementAt(i);
                id = Elements.id;
                /*
                Doing some code
                */                                               
            }     
             int i = db.Delete<tablename>(new tablename() { Sid = 26 });
        }
    }
    catch (Exception ex)
    {

    }
}   

其中“Sid”是我数据库中的列,编号为“26”我将获得 n 行 所以,使用 for 循环我需要做一些代码,在 for 循环之后我需要删除数据库中 Sid(26) 的记录,所以在这一行

int i = db.Delete<tablename>(new tablename() { Sid = 26 });

我收到unable to close due to unfinalised statements 异常,所以我的问题是如何在 sqlite3 中完成语句,显然 SQLite3 有一个用于销毁以前的 DB 调用的 finalize 方法,但我不确定如何实现这一点。请帮帮我。

【问题讨论】:

    标签: c# sqlite windows-8 microsoft-metro windows-runtime


    【解决方案1】:

    在幕后,sqlite-net 做了一些令人惊奇的事情,试图为您管理查询和连接。

    例如,行

    var data = db.Table<tablename>().Where(...)
    

    实际上并不建立连接或对数据库执行任何操作。相反,它会创建一个名为 TableQuery 的类的实例,该类是可枚举的。

    当你打电话时

    int iDataCount = data.Count();
    

    TableQuery 实际执行

    GenerateCommand("count(*)").ExecuteScalar<int>();
    

    当你打电话时

    Elements = data.ElementAt(i);
    

    TableQuery 实际调用

    return Skip(index).Take(1).First();
    

    Take(1).First() 最终调用 GetEnumerator,它编译 SQLite 命令,使用 TOP 1 执行它,并将结果序列化回您的数据类.

    因此,基本上,每次您调用 data.ElementAt 时,您都在执行另一个查询。这与标准 .NET 枚举不同,在标准 .NET 枚举中,您只是访问集合或数组中的元素。

    我相信这是您问题的根源。我建议您不要获取计数并使用 for(i, ...) 循环,而只需执行 foreach (tablename tn in data)。这将导致一次获取所有记录,而不是在循环中逐条记录。仅此一项就足以关闭查询并允许您在循环期间删除表。如果没有,我建议您创建一个集合并在循环期间将每个 SID 添加到集合中。然后,在循环后返回并在另一遍中删除 sids。最坏的情况,你可以关闭循环之间的连接。

    希望对您有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-12-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-21
      • 2023-03-11
      • 1970-01-01
      相关资源
      最近更新 更多