7

我遇到了 Xamarin.Android 应用程序的缓慢启动体验。

第一个 DbContext 创建大约需要 4.5 秒(上下文有 24 个表)。起初我认为这是因为 EF Core 需要时间来扫描 DbContext 中的实体类并构建模型(这对于大型 DbContext 是有意义的)。

于是,我创建了一个只有一张表的测试 DbContext 来检查创建模型的时间对模型中表的数量的关系:

public class Log
{
    [Key]
    public int EntityId { get; set; }
    public string Timestamp { get; set; }
    public string Level { get; set; }
    public string Exception { get; set; }
    public string RenderedMessage { get; set; }
    public string Properties { get; set; }
}

public class ApplicationLogDbContext : DbContext
{
    public ApplicationLogDbContext(DbContextOptions<ApplicationLogDbContext> options)
        : base(options) { }

    public DbSet<Log> Logs { get; set; }
}

DbContext 测试代码:

var options = new DbContextOptionsBuilder<ApplicationLogDbContext>()
    .UseSqlite("Data Source=/storage/emulated/0/Android/data/***/files/ApplicationLog.db")
    .Options;
var logContext = new ApplicationLogDbContext(options);
logContext.Database.EnsureCreated();

在我的三星 Galaxy S7 上执行此代码需要3.3 秒。该测试表明尝试某些解决方案是不合适的:

  • 使用更少的实体类(减少表之间的连接);
  • 将一个应用程序 DbContext 拆分为几个小的上下文。

我还了解到:

  • EF Core 没有自动迁移(我不需要禁用它);
  • 我删除了代码优先方法,但它只是部分帮助将 DbContext 初始化时间减少到 4 秒;
  • 如果我删除带有 EnsureCreated 的行,第一个请求的执行时间会同时增加;
  • 有很多类似的问题(这里,GitHub),但他们没有解决方案。甚至 EF6 也报告了此类问题;
  • 安装 Microsoft.EntityFrameworkCore.Sqlite 5.0.0-preview.6.20312.4 后我没有注意到任何重大变化(应用程序具有相同的执行时间:~ 3.3 秒);
  • PRAGMA journal_mode=WAL; 提高初始化速度(EF Core 2.2)。这并不稳定,但有时初始化时间会减少 300-400 毫秒。
  • 如果应用程序有 2 个用于不同数据库的 DbContext(第一个具有一个实体,第二个具有 25 个实体)第二个上下文的 EF Core 初始化时间将大幅减少到~1 秒。第一次上下文初始化仍然很慢;
  • 在没有附加调试会话的情况下,初始化完成速度更快 (~30%)。

EF Core 5 Preview 6 GitHub示例

在此处输入图像描述 在此处输入图像描述

我可以使用什么方法以某种方式向用户隐藏此初始化时间,但获取主要活动的数据?

是否有任何配置提示可以帮助增加默认配置初始化时间?

运行 .NET 5 时性能会提高吗?

4

0 回答 0