7秒的EF启动时间,即使对于微小的DbContext也是如此

我正在尝试减少基于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(null); var config = new EntityTypeConfiguration(); 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(null); var config = new EntityTypeConfiguration(); 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().FirstOrDefault(); var t1 = DateTime.Now - start; start = DateTime.Now; var apt2 = new MyDbContext2(connectionString).Set().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连接可能会导致问题。

  1. 我首先尝试使用原始SqlConnection运行随机查询,并使用相同的连接字符串创建命令。 这花了1秒钟,并没有影响DbContext初始化的时间。
  2. 然后,我尝试使用连接字符串创建一个SqlConnection,并将其传递给DbContext的构造函数,该构造函数接受连接。 我传递了contextOwnsConnection = false。 这也使DbContext初始化时间没有差别。
  3. 最后,我尝试使用相同的凭据和连接字符串选项通过管理工作室进行连接。 这几乎是瞬间完成的。
  4. 在dotTrace配置文件中,它将SqlConnectionFactory.CreateConnection(connectionString)测量为0.7秒,这与原始SQL时间一致。

编辑:我想知道延迟是每个连接还是只有一次。 因此,我尝试将MyDbContext1和MyDbContext2连接到不同服务器上完全不同的数据库。 无论首先连接哪个数据库,这个DID都没有区别:使用第一个DbContext需要大约7秒,而使用第二个上下文非常快。

在将您编写的代码放入其自己的项目后,我发现该项目的平台目标对EF框架的启动时间有很大影响。

在针对x64平台时,我收到了类似于你的结果(在第一个DbContext上旋转7秒,在第二个DbContext上旋转<1秒)。 当以x86为目标时,第一个DbContext的旋转时间减少约4秒,减少到3.34633秒,而第二个DbContext的时间与x64情况相同。

我不确定为什么会发生这种情况,但它必须与entity framework如何在不同环境中初始化自身有关。 我在这里发布了一个单独的问题。

根据几条评论,第二个运行如此之快的原因是由于连接管理器缓存了连接。 这让我相信获得初始连接是个问题。

要尝试的事情:

  1. 更改连接字符串以使用数据库服务器的IP地址而不是其名称。

  2. 使用完全相同的凭据和机制,使用SQL Management Studio连接到数据库服务器。 从需要7秒钟的机器上完成。 假设需要一段时间,请调查以查看正在使用的协议,并确保所需的协议是列表中的第一个协议。

  3. 将网络分析仪放在您的机器上并观察其function。