我試圖減少基於EF的應用程序的啓動時間,但是我發現無法減少初始讀取時間低於7秒的時間,即使對於單一實體上下文。特別奇怪的是,這次不是特定於上下文類型的。即使對於微小的DbContext也需要7秒的EF啓動時間
任何人都可以解釋導致這些緩慢時間和/或如何讓事情運行得更快嗎?
下面是完整的示例代碼:
在我的數據庫,我有一個名爲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秒似乎太高而無法歸因於此。
我使用EF 4.3.1和.NET 4 VS 2010
預先感謝您的幫助!
編輯:有人建議打開SQL連接可能會導致問題。
- 我第一次嘗試運行一個隨機查詢使用原始SqlConnection和創建命令具有相同的連接字符串。這花了1秒鐘,並沒有影響DbContext初始化的時間。
- 然後我試着用連接字符串創建一個SqlConnection並將它傳遞給需要連接的DbContext構造函數。我傳遞了contextOwnsConnection = false。這在DbContext初始化時間中也沒有區別。
- 最後,我嘗試使用相同的證書和連接字符串選項通過管理工作室進行連接。這幾乎是瞬間的。
- 在dotTrace配置文件中,它測量SqlConnectionFactory.CreateConnection(connectionString)爲0.7秒,這與原始SQL時間一致。
編輯:我想知道延遲是每個連接或只有一次。因此,我試圖讓MyDbContext1和MyDbContext2連接到不同服務器上完全不同的數據庫。無論首先連接哪個數據庫,這個DID都沒有什麼不同:使用第一個DbContext花費了大約7秒,而使用第二個上下文非常快。
[性能注意事項(實體框架)](http://msdn.microsoft.com/en-us/library/cc853327.aspx) – jrummell
@jrummell:這是一個很好的鏈接(我已經閱讀過)。您認爲是否有特定的部分解決了我的問題? – ChaseMedallion
首先,你應該使用StopWatch類來做時機。它更準確。其次,預生成視圖可能會有所幫助(但在這樣一個小環境下,我看不出它會有多大幫助)。您可以使用EF Power Tools從DbContext自動生成視圖。 –