删除sqlite数据库文件。

7

我正在开发一个C#应用程序,它的后端是sqlite。在我的应用程序中,我有一个按钮来清除数据库(删除.db文件并重新创建带有一些初始数据的新文件)。有时候,当我尝试删除数据库时,它会说无法删除,因为它正在被另一个进程使用。在删除之前,我正在使用关闭连接、释放和清空池函数。即使这样,它仍然会抛出相同的异常。以下是我的代码:

string targetDataBaseFilePath = Path.Combine(dataDirectoryPath, "local.db");               
ThingzDatabase.Create(targetDataBaseFilePath, "touchdb");

在 create 函数中,我定义了以下代码,出现了错误:
if (File.Exists(DatabaseFileName))
{
    try
    {
        ThingzDatabase.localdb.conn.Close();
        ThingzDatabase.localdb.conn.Dispose();
        SQLiteConnection.ClearAllPools();
    }
    catch (Exception)
    {
    }
    File.Delete(DatabaseFileName); //error throws from here.                       
}

我该如何防止错误被抛出?

7个回答

7
FileInfo fi = new FileInfo(DatabasePath);
try
{
    if (fi.Exists)
    {
        SQLiteConnection connection = new SQLiteConnection("Data Source=" + DatabasePath + ";");
        connection.Close();
        GC.Collect();
        GC.WaitForPendingFinalizers();
        fi.Delete();
    }
}
catch(Exception ex)
{
    fi.Delete();
}

DatabasePath 是您的数据库文件路径。


1
我使用了"File.Delete(dbPath);"而不是"FileInfo",它起作用了,谢谢! - Tahirhan

2

最后我只好自己去问问题。解决方法是让垃圾回收运行一段时间。


2
ThingzDatabase.localdb.conn.ClearAllPools(); 

我相信这应该是那行代码的调用。

这绝对需要更多的声音。在我的情况下,我正在使用Setup/Teardown进行一些测试,并且依赖GC调用似乎非常不专业。请注意,自那时以来API似乎已经发生了变化,现在它是SQLiteConnection的静态方法,您现在可以像这样调用它:SQLiteConnection.ClearAllPools() - Luke Marlin

1
在连接字符串中使用 Pooling=False; 我曾经遇到过开启池化的同样问题。

1

我相信你还没有处理从API返回的某些内容。

你使用哪个sqlite包装器?你引用了自定义函数的使用,它们是做什么的?


我有一个对数据库连接的引用,但没有正确地处理它的释放。一旦我解决了这个问题,这个问题就被解决了。做得好。 - Jacob Robbins
我曾经遇到过同样的问题,后来发现在ADO.NET中有一个SQLiteCommand没有使用"using"。 - Petr

-1

您可以使用像Mark Russinovich的 procmon这样的工具。
然后,您可以根据文件名过滤显示内容。
完成此操作后,您可以准确地查看哪个进程正在锁定该文件,并进行相应的调试。


-1

我看到很多人使用进程来处理问题。但是sqlite有一个方法可以解决这个问题。

VACUUM命令会重建数据库文件,将其重新打包为最小的磁盘空间。

https://sqlite.org/lang_vacuum.html


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接