Оптимизируйте соединение с БД SQLite, используя EF Core в приложении UWP - PullRequest
0 голосов
/ 05 апреля 2019

В настоящее время я работаю над приложением CW UWP, которое работает на операционной системе Windows 10 IoT Core на процессоре ARM.Для этого приложения я использую базу данных SQLite для своей персистентности, с Entity Framework Core в качестве моего ORM.

Я создал свой собственный DBContext и при запуске вызываю функцию Migrate, которая создает мою БД.Я также могу успешно создать экземпляр DBContext в моей основной логике, который может успешно читать / записывать данные, используя модель.Пока все хорошо.

Однако я заметил, что производительность создания DbContext для каждого взаимодействия с БД мучительно медленная.Хотя я могу гарантировать, что только мое приложение имеет доступ к базе данных (я работаю на пользовательском оборудовании с управляемой программной средой), в моем приложении есть несколько потоков, которым требуется доступ к базе данных через DbContext.

Мне нужно найти способ оптимизировать соединение с моей базой данных SQLite таким образом, чтобы он был безопасным для потоков в моем приложении.Как я упоминал ранее, мне не нужно беспокоиться о каких-либо внешних приложениях.

Сначала я попытался создать объект SqliteConnection извне, а затем передать его каждому создаваемому DbContext:

_connection = new SqliteConnection(@"Data Source=main.db");

... и затем сделайте это доступным для моего DbContext и используйте его в переопределении OnConfiguring:

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
    optionsBuilder.UseSqlite(_connection);
}

... и затем используйте DbContext в моем приложении, например так:

using (var db = new MyDbContext())
{
    var data = new MyData { Timestamp = DateTime.UtcNow, Data = "123" };
    db.MyData.Add(data);
    db.SaveChanges();
}
// Example data read
MyDataListView.ItemsSource = db.MyData.ToList();

Используя вышеуказанный подход, я заметил, что соединение закрывается автоматически при удалении DbContext, независимо от того, что соединение было создано извне.Таким образом, в результате возникает исключение во второй раз, когда я создаю DbContext с подключением.

Во-вторых, я попытался создать один DbContext один раз статически и поделиться им со всем моим приложением.Поэтому вместо создания DbContext в выражении using, как описано выше, я попробовал следующее:

// Where Context property returns a singleton instance of MyDbContext
var db = MyDbContextFactory.Context;
var data = new MyData { Timestamp = DateTime.UtcNow, Data = "123" };
db.MyData.Add(data);
db.SaveChanges();

Это дает мне повышение производительности, на которое я надеялся, но я быстро понял, что это не безопасно для потоков, и более широкое чтение имеетподтвердил, что я не должен этого делать.

Так есть ли у кого-нибудь совет, как улучшить производительность при доступе к базе данных SQLite в моем случае с EF Core и многопоточным приложением UWP?Большое спасибо заранее.

1 Ответ

0 голосов
/ 24 апреля 2019

Во-вторых, я попытался создать один статический DbContext один раз и поделиться им со всем моим приложением. Поэтому вместо создания DbContext в выражении using, как описано выше, я попробовал следующее ... Это дает мне улучшения производительности, на которые я надеялся, но я быстро понял, что это не безопасно для потоков, и более широкое чтение подтвердило, что я не должен делать это.

Я не знаю, почему мы не должны этого делать. Может быть, вы можете поделиться чем-то о том, что вы читаете. Но я думаю, вы можете сделать объект DBContext глобальным и статическим, а когда вы захотите сделать CRUD, вы можете сделать это в основном потоке следующим образом:

await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
{
    //App.BloggingDB is the static global DBContext defined in App class 
    var blog = new Blog { Url = NewBlogUrl.Text };
    App.BloggingDB.Add(blog);
    App.BloggingDB.SaveChanges();
});

Но утилизируйте DBContext в нужное время, так как он не удаляется автоматически.

...