Почему я не могу использовать расширения файлов в файлах Entity Framework Core Sqlite? - PullRequest
0 голосов
/ 26 мая 2018

Когда я пытаюсь использовать Entity Framework Core с Sqlite и расширением файла .db или .sqlite, я получаю сообщение об ошибке

SqliteException: ошибка SQLite 14: 'невозможно открыть базу данныхfile '

Если я удаляю расширение файла, то оно работает нормально.

Я не очень знаком с Entity Framework Core, и в прошлом я использовал такие вещи, как npoco,Я работаю над DataStorage и DataAggregator, и у меня возникают проблемы, которые требуют реализации некоторых хакеров.Мне это не нравится, и это заставляет меня чувствовать себя грязно.

Если я удаляю .db из строки подключения, то он работает просто отлично, но если я оставлю любое расширение файла включенным (у меня толькопробовал .db и .sqlite), я получаю эту ошибку.

Шаги для воссоздания:

  1. Клон https://github.com/EdLichtman/DataStorageService

  2. dotnet run Это решение (или поиграйте с юнит-тестами) и перейдите к AggregateResults ControllerAction в вашем браузере.Он попытается найти все файлы, которые заканчиваются на .db, и все, которые заканчиваются на _db_metadata.json, и не найдет ни одного, и вернет «0» на страницу браузера.

  3. Теперь перейдитев DataStorageService\DataStorageService\TransmittedFiles хранилище и очистите его.Перейти к Endpoints\DataStorage\AggregateData\AggregateDataContext.cs.Закомментируйте строки

    if (OperatingSystemHelpers.IsOSWindows)...
    

    до

    .Remove(connectionStringFileLocation.Length - 3);
    

    Попытайтесь сделать то же самое, что и раньше, и вы увидите, что 1) файл AggregateData.db все еще создается в TransmittedFiles,и 2) вы должны увидеть SqliteError 14.

Если вы снова очистите папку TransmittedFiles и попробуете ее с предложением OperatingSystemHelpers, вы увидите, что он работает.Это означает, что файл не существует.

1 Ответ

0 голосов
/ 29 мая 2018

Проблема возникает из-за того, что предыдущее соединение все еще имеет доступ к файлу.

Как уже упоминалось в приведенном ниже потоке, реализация Cqlite в C # имеет причуду, когда после .Close () соединение не очищается до тех пор, покасборщик мусора запускается

System.Data.SQLite Close () не освобождает файл базы данных

Чтобы исправить это, вы можете добавить IDisposable в ваш IAggregateDataRepository и реализовать нечто подобное, напримерследующий метод удаления:

public void Dispose()
{
   _database.Dispose();
   GC.Collect();
   GC.WaitForPendingFinalizers();
}

Вам нужно будет вызвать диспозиторов в ваших тестах, это можно сделать, добавив следующее в начало вашего метода TearDown:

if (_aggregateDataRepository != null) 
{
   _aggregateDataRepository.Dispose();
}

КакДополнительный совет, если вы добавите эту строку в конец конструктора контекста приложения, это обеспечит вам постоянный доступ в режим «Write Ahead Log», который больше подходит для нескольких соединений.Это не нужно для устранения проблемы, но, поскольку вы собираетесь создать интерфейс успокоительного веб-API на sqlite, он поможет при одновременных вызовах.

Database.ExecuteSqlCommand("PRAGMA journal_mode=WAL;");

Дополнительные сведения https://www.sqlite.org/wal.html

...