我遇到了 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 时性能会提高吗?