我正在尝试减少基于 EF 的应用程序的启动时间,但我发现即使对于单实体上下文,我也无法将初始读取所需的时间减少到 7 秒以下。特别奇怪的是,这一次不是特定于上下文类型的。
谁能解释导致这些缓慢时间的原因和/或我如何让事情运行得更快?
这是完整的示例代码:
在我的数据库中,我有一个名为 se_stores 的表,其中包含一个主键列 AptId:
// a sample entity class
public class Apartment
{
public int AptId { get; set; }
}
// two identical DbContexts
public class MyDbContext1 : DbContext
{
public MyDbContext1(string connectionString) : base(connectionString)
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
Database.SetInitializer<MyDbContext1>(null);
var config = new EntityTypeConfiguration<Apartment>();
config.HasKey(a => a.AptId).ToTable("se_stores");
modelBuilder.Configurations.Add(config);
base.OnModelCreating(modelBuilder);
}
}
public class MyDbContext2 : DbContext
{
public MyDbContext2(string connectionString)
: base(connectionString)
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
Database.SetInitializer<MyDbContext2>(null);
var config = new EntityTypeConfiguration<Apartment>();
config.HasKey(a => a.AptId).ToTable("apartments");
modelBuilder.Configurations.Add(config);
base.OnModelCreating(modelBuilder);
}
}
// finally, I run this code using NUnit:
var start = DateTime.Now;
var apt1 = new MyDbContext1(connectionString).Set<Apartment>().FirstOrDefault();
var t1 = DateTime.Now - start;
start = DateTime.Now;
var apt2 = new MyDbContext2(connectionString).Set<Apartment>().FirstOrDefault();
var t2 = DateTime.Now - start;
Console.WriteLine(t1.TotalSeconds + ", " + t2.TotalSeconds);
它可靠地打印如下内容:7.5277527, 0.060006。当我将测试切换为首先使用 MyDbContext2 时,我得到了相同的结果(因此无论哪个 DbContext 先初始化都会发生这种情况)。我还尝试使用 EF 电动工具预生成视图。这将第一个上下文的时间减少到大约 6.8 秒,因此只是一个小小的胜利。
我知道 DateTime.Now 是一种糟糕的分析方法,但是在使用 dotTrace 时这些结果仍然存在。我也知道第一次运行一些代码会调用 JITing 成本,但是 7 秒似乎太高了,不能归因于此。
我在 VS 2010 中使用 EF 4.3.1 和 .NET 4。
在此先感谢您的帮助!
编辑:有人建议打开 SQL 连接可能会导致问题。
- 我首先尝试使用原始 SqlConnection 运行随机查询并使用相同的连接字符串创建命令。这需要 1 秒,并且不影响 DbContext 初始化的时间。
- 然后,我尝试使用连接字符串创建一个 SqlConnection 并将其传递给 DbContext 的接受连接的构造函数。我通过了 contextOwnsConnection=false。这对 DbContext 初始化时间也没有影响。
- 最后,我尝试使用相同的凭据和连接字符串选项通过管理工作室进行连接。这几乎是瞬间的。
- 在 dotTrace 配置文件中,它测量 SqlConnectionFactory.CreateConnection(connectionString) 耗时 0.7 秒,这与原始 SQL 时间一致。
编辑:我想知道延迟是每次连接还是一次。因此,我尝试让 MyDbContext1 和 MyDbContext2 连接到不同服务器上完全不同的数据库。无论首先连接到哪个数据库,这都没有区别:第一个 DbContext 的使用大约需要 7 秒,而第二个上下文的使用速度非常快。