首页 > 解决方案 > 在 UWP 应用中使用 EF Core 优化与 SQLite DB 的连接

问题描述

我目前正在开发在 ARM 处理器上的 Windows 10 IoT Core OS 上运行的 C# UWP 应用程序。对于这个应用程序,我使用 SQLite DB 进行持久化,并使用 Entity Framework Core 作为我的 ORM。

我已经创建了自己的 DBContext 并在启动时调用了创建我的数据库的 Migrate 函数。我还可以在我的主逻辑中成功创建一个 DBContext 实例,该实例可以使用该模型成功读取/写入数据。到目前为止一切都很好。

但是,我注意到为与数据库的每次交互创建 DbContext 的性能非常缓慢。尽管我可以保证只有我的应用程序在访问数据库(我在具有受控软件环境的自定义硬件上运行),但我的应用程序中确实有多个线程需要通过 DbContext 访问数据库。

我需要找到一种方法,以在我的应用程序中以线程安全的方式优化与我的 SQLite DB 的连接。正如我之前提到的,我不必担心任何外部应用程序。

起初,我尝试在外部创建一个 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 并在整个应用程序中共享它。因此,我没有在上面的 using 语句中创建 DbContext,而是尝试了以下操作:

// 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();

这为我提供了我希望的性能改进,但我很快意识到这不是线程安全的,更广泛的阅读已经证实我不应该这样做。

那么,在我使用 EF Core 和多线程 UWP 应用程序访问 SQLite DB 时,是否有人对如何提高性能有任何建议?提前谢谢了。

标签: sqliteuwpdbcontextef-core-2.0

解决方案


其次,我尝试静态创建一个 DbContext 并在整个应用程序中共享它。因此,我没有在上面的 using 语句中创建 DbContext,而是尝试了以下...这个。

我不知道为什么我们不应该这样做。也许你可以分享你读到的东西。但我认为,您可以使 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,因为它不会自动处置。


推荐阅读