部署带有嵌入式SQLite的WinForm应用程序

7

我正在部署一个使用VS 2008在XP SP3上构建的Winform应用程序。

我创建了一个空架构的数据库,将其放置在项目的根文件夹中,并在属性中选择了Build Action嵌入式资源Copy to Output directory始终复制。现在,我将连接字符串从app.config connectionString部分中删除,并在appSetting中添加了一个条目:key="database";value="mydb.db;Version=3"。

因此,为了创建我的connectionString,我使用了:

 SQLiteConnection con = new SQLiteConnection("Data Source=" + Path.Combine(Application.StartupPath, ConfigurationManager.AppSettings["database"]));

一切都运作正常,我使用一个安装程序打包了这个应用程序。但是在安装应用程序后,数据库无法被找到,因此我不得不将数据库复制到设置项目中的“应用程序文件夹”才能使其工作。
我认为数据库由于“总是复制”的缘故应该位于应用程序dll中,但我无法访问它。那么我到底做错了什么?
我怀疑我应该仅连接到根数据库,而不是使用“Application.StartupPath”。但是我想请教最佳实践,因为虽然我的方法可行,但看起来仍然像一个变通方法。所以,请问有人能与我分享他的经验吗?感谢您的阅读。

我猜这更像是一个“嵌入文件”的问题,而不是SQLite的问题。 - M.A. Hanin
1
是的,它是的。但是SQLite是最常用的嵌入式数据库之一,因此大多数使用SQLite的人可能知道如何嵌入数据库,对吧? - black sensei
1个回答

5

嵌入式资源表示数据库被嵌入到您的dll中。在这种情况下,复制到输出目录设置不适用,这是用于生成操作:内容的。

使用嵌入式数据库时,您基本上需要在首次使用时取消嵌入。为此,请从程序集中读取它并将其存储到文件中。

class EmbeddedResourceTest
{
    public static void Test()
    {
        string path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Test.db");

        using(var resourceStream = typeof(EmbeddedResourceTest).Assembly.GetManifestResourceStream("Test.db"))
        {
            using(var fileStream = File.OpenWrite(path))
            {
                CopyStream(resourceStream, fileStream);
            }
        }

        // now access database using 'path'
    }

    public static void CopyStream(Stream inputStream, Stream outputStream)
    {
        CopyStream(inputStream, outputStream, 4096);
    }

    public static void CopyStream(Stream inputStream, Stream outputStream, int bufferLength)
    {
        var buffer = new byte[bufferLength];
        int bytesRead;
        while ((bytesRead = inputStream.Read(buffer, 0, bufferLength)) > 0)
        {
            outputStream.Write(buffer, 0, bytesRead);
        }
    }
}

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