我正在使用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调用,但我不知道如何实现它。请帮帮我。
答案 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。最糟糕的情况是,您可以关闭循环之间的连接。
希望有所帮助。