Как я могу встроить базу данных SQLite в .NET DLL, а затем использовать ее из C #?

В настоящее время я работаю над оценкой проекта, который планирую.

Недавно я рассмотрел решения для механизма хранения данных для своего приложения и во время исследования наткнулся на SQLite. В настоящее время я использую SQLite с оболочкой System.Data.SQLite.

Мне очень нравится, как это работает, но у меня есть одна проблема, которую я не мог исправить, и я также не нашел помощи по моей проблеме в Интернете.

Я хотел бы, чтобы моя база данных SQLite была встроена в одну из моих библиотек DLL приложений (например, Title.Storage.dll) для использования в этой DLL. Это возможно?

Как тогда я могу получить доступ к базе данных?

Было бы здорово, если бы я мог использовать что-то вроде:

SQLiteConnection con = new SQLiteConnection();
con.ConnectionString="DataSource=Title.Storage.storage.db3";
con.Open();

Заранее спасибо и с наилучшими пожеланиями,

3Fox


person chrischu    schedule 26.04.2009    source источник
comment
Это невозможно. Как бы вы записали в базу данных? Для записи придется открыть сборку. Не отвечаю, потому что не могу предоставить технические подробности.   -  person    schedule 26.04.2009
comment
Даже если бы это было возможно, я бы предположил, что это свело бы с ума некоторые системы безопасности - большие, постоянные изменения в файле кода.   -  person dommer    schedule 26.04.2009
comment
Если у вас есть небольшой объем данных только для чтения, которые вы хотите запросить, это, вероятно, сработает нормально - считайте ресурс в базу данных в памяти и запросите его.   -  person Shog9    schedule 26.04.2009
comment
Возможно, я ошибаюсь, но я помню, когда имел дело с Dotnet 2, был способ встроить базу данных sql express в exe / dll.   -  person Itay Moav -Malimovka    schedule 26.04.2009
comment
@Will - мы не хотим писать в базу данных - мы хотим использовать ее в качестве отправной точки для :memory: размещенной базы данных, которая не обязательно нигде сохраняется. Решения, которые сначала извлекают встроенный ресурс в файл, не идеальны - действительно ограничивают полезность баз данных в памяти.   -  person Jason Kleban    schedule 08.05.2013
comment
@ Shog9 - как мы можем прочитать ресурс в базу данных в памяти?   -  person Jason Kleban    schedule 08.05.2013
comment
@ uosɐſ: почти так же, как любой файл в базе данных SQLite в памяти; немного покопаться, обе части этого довольно хорошо задокументированы. Например: stackoverflow.com/questions/433171/ и stackoverflow.com/questions/14508502/   -  person Shog9    schedule 08.05.2013
comment
@ Shog9 - я могу создать базу данных sqlite в памяти, и я могу читать двоичный файл из встроенного ресурса, но я не знаю, как загрузить базу данных памяти с уже существующим изображением базы данных, не загружая его (в какой-то момент) из автономного файла по пути.   -  person Jason Kleban    schedule 08.05.2013
comment
@ uosɐſ: я бы, вероятно, просто сохранил данные в каком-то другом формате (CSV, XML) и загружал / анализировал / создавал базу данных во время выполнения. Если вы действительно заинтересованы в загрузке базы данных SQLite из потока, я бы опубликовал это как отдельный вопрос.   -  person Shog9    schedule 08.05.2013


Ответы (5)


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

person Samuel    schedule 26.04.2009

Это невозможно как таковое. Что вы можете сделать, так это встроить db в свой проект dll и выгрузить его в определенное место в файловой системе (может быть AppData?), А затем читать и писать оттуда. Размещение db непосредственно внутри исполняемого файла (или dll) может быть не очень хорошей идеей в том смысле, что оно увеличивает размер приложения, помимо того, что это технически невыполнимо.

Наличие единственного исполняемого файла для распространения - дело вкуса, которое мне нравится. В твоем случае проблем больше. Речь идет не только о встраивании одного файла db, а как насчет связанных с ним dll? Шагов 2:

1) Добавьте необходимые библиотеки dll (System.Data.SQLite?), Связанные с вашей базой данных, в ваш проект как Embedded Resource (не обязательно Resource file), и пусть система автоматически разрешит конфликты сборок. Узнайте здесь, как это сделать.

2) Теперь либо добавьте ваш файл db в свой Resources вашего проекта (и извлеките его)

static void DumpDatabase()
{
    var dbFullPath = Utility.GetDbFullPath(); //your path
    if (File.Exists(dbFullPath))
        return; //whatever your logic is

    File.WriteAllBytes(dbFullPath, Properties.Resources.myDb);
}

или даже лучше не встраивайте базу данных как таковую в свой проект, а напишите логику для создания базы данных в вашем приложении. Что делать, если завтра вам нужно будет сменить версию SQLite, скажем, с 3 на 4? При первом подходе вам нужно создать для себя базу данных и повторно встроить ее в проект. Но если вы пишете логику для создания db в своем приложении, то обновление версии SQLite - это просто вопрос изменения dll ADO.NET (код остается прежним). Может быть так:

static void DumpDatabase()
{
    var dbFullPath = Utility.GetDbFullPath();
    if (File.Exists(dbFullPath))
        return; //whatever your logic is

    CreateDb(dbFullPath);
}

static void Create(string dbFullPath)
{
    SQLiteConnection.CreateFile(dbFullPath);

    string query = @"

    CREATE TABLE [haha] (.............)
    CREATE TABLE ..............";

    Execute(query);
}

И в строке подключения добавить FailIfMissing=False;

person nawfal    schedule 11.11.2012

Если вы используете NTFS, вы можете использовать альтернативный поток данных. В моем проекте мы скрываем базу данных SQLite внутри другого файла, используя альтернативный поток под названием: DB.

person Anthony Brien    schedule 23.05.2009
comment
что произойдет, если я скопирую файл в раздел FAT32 и обратно? - person Lucas; 23.05.2009
comment
Вы потеряете альтернативный поток после копирования файла на раздел FAT. - person mateusza; 02.06.2009

Я не думаю, что хранение данных в DLL - хорошая идея, но есть грязный способ сделать это.

Чтобы загрузить данные из DLL:

  1. Используйте System.Reflection.Assembly, чтобы загрузить строку из файла DLL. (Строка - дамп БД)
  2. Создать в памяти пустую базу данных SQLite.
  3. Использовать загруженную строку как запрос к БД для восстановления ее содержимого.

Теперь вы можете делать любые запросы в памяти.

Чтобы сохранить данные в DLL:

  1. Выгрузить содержимое БД в строку.
  2. Создать временный файл, содержащий SQL-дамп, завернутый в код C #.
  3. Скомпилируйте его, используя "csc" (или "gmcs" в Mono).

Это глупо, но должно работать. Надеюсь, ты никогда не будешь таким программировать.

person mateusza    schedule 31.05.2009

SQLite упакован и распространяется как один файл C с несколькими (я думаю, 3) заголовочными файлами. Это означает, что вы можете скомпилировать всю программу из 50000 строк с помощью одной команды компиляции и получить файл .o. Оттуда вы можете связать его с DLL вашего приложения с другими файлами, которые вы связываете с этой DLL.

После встраивания sqlite3.o в DLL приложения символы в его API SQLite становятся доступными для ваших программ так же, как другие библиотеки DLL C / C ++ становятся доступными для ваших программ на C # / VB.

Посетите www.sqlite.org/amalgamation.html для получения дополнительной информации.

person Community    schedule 24.05.2009
comment
Это было совершенно не то, чего я пытался достичь. Я хотел встроить файл ‹u› базы данных ‹/u› в dll, а не в dll, которая позволяет мне получить к нему доступ. - person chrischu; 31.05.2009