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

Cha*_*ion 11 c# linq performance linq-to-entities entity-framework

我正在尝试减少基于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);
Run Code Online (Sandbox Code Playgroud)

它可靠地打印如下内容: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秒,而使用第二个上下文非常快.

Sid*_*awy 8

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

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

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