完成SQLite 3语句

时间:2012-08-20 14:46:21

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

我正在使用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调用,但我不知道如何实现它。请帮帮我。

1 个答案:

答案 0 :(得分:2)

在封面下,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枚举不同。

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

希望有所帮助。