развертывание приложения winform со встроенным sqlite - PullRequest
7 голосов
/ 22 апреля 2010

Я развертываю приложение winform, созданное с версией 2008 0n XP sp3.

Я создал базу данных с пустой схемой, которую я поместил в корневую папку проекта и в свойствах, которые я выбрал 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"]));

Все отлично работает, и я упаковал приложение с проектом установки. Теперь, после установки приложения, база данных не может быть найденаи я был обязан скопировать базу данных в Application Folder в проекте установки для его работы.

что я думал, что db должен быть в dll приложения из-за copy always. Но я не могу получить к нему доступ. Так что именно я сделал не так?

Я подозреваю, что я должен был просто подключиться к корневому БД, что означает не использовать Application.StartupPath

Но я здесь спрашиваю лучшие практики, потому что то, что я сделал, работает, но все еще смотриткак обходной путь, так что, пожалуйста, кто-нибудь может поделиться своим опытом со мной?спасибо за чтение

1 Ответ

5 голосов
/ 23 апреля 2010

Embedded Resource означает, что база данных встроена в вашу DLL. Параметр Copy to output directory не применяется в этом случае, он используется для Build Action: Content.

Со встроенной базой данных вам, по сути, придется ее встраивать при первом использовании. Для этого прочитайте его из сборки и сохраните в файл.

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);
        }
    }
}
...