2012-02-13 43 views
3

從廣泛的谷歌搜索,看起來我不是第一個遇到這個問題的人,但我一直無法找到任何能夠圓滿解決它的人 - 我正在整合與一個遺留數據庫,我只是試圖集成一個單一的表(目前),但我對這個模型的第一個查詢需要大約12秒左右的時間來執行。如預期的那樣,第二個電話幾乎是即時的。實體框架代碼 - 首先是很慢

下面是我的實體框架代碼優先設置的全部:

public class PortalDatabase : DbContext 
{ 
    public DbSet<User> Users { get; set; } 

    public PortalDatabase():base("portalDatabase") 
    { 
    } 

    protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     User.ConfigureEntity(modelBuilder.Entity<User>()); 
    } 
} 

public class User 
{ 
    public int ID { get; set; } 

    public string FullName { get; set; } 

    /// <summary> 
    /// Internal representation of the IsDisabled flag. This should not be 
    /// written to; use <see cref="IsDisabled"/> instead. 
    /// </summary> 
    internal byte IsDisabledInternal { get; set; } 

    public bool IsDisabled 
    { 
     get { return Convert.ToBoolean(this.IsDisabledInternal); } 
     set { this.IsDisabledInternal = Convert.ToByte(value); } 
    } 

    public int LoginAttempts { get; set; } 

    public string EmailAddress { get; set; } 

    public string Password { get; set; } 

    internal static void ConfigureEntity(EntityTypeConfiguration<User> entity) 
    { 
     entity.ToTable("Users"); 

     entity.Property(model => model.ID) 
      .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity) 
      .HasColumnName("UserID"); 

     entity.Property(model => model.FullName) 
      .HasColumnName("UserName"); 

     entity.Property(model => model.IsDisabledInternal) 
      .HasColumnName("AccountLocked"); 

     entity.Ignore(model => model.IsDisabled); 

     entity.Property(model => model.LoginAttempts) 
      .HasColumnName("LoginAttempts"); 

     entity.Property(model => model.EmailAddress) 
      .HasColumnName("EmailAddress"); 

     entity.Property(model => model.Password) 
      .HasColumnName("Password"); 
    } 
} 

此代碼示例需要8-12秒來執行:

PortalDatabase database = new PortalDatabase(); 

    IEnumerable<User> users = from user in database.Users 
           where user.ID == 66 
           select user; 

我明白,這個問題是做元數據生成,這是隻做一次,其中according a comment from ScottGu「提高性能很多」:

Th e「代碼優先」庫使用與傳統方法相同的底層EF,因此性能特徵應該大致相同。 「代碼優先」庫也包含了一些智能特性,因此爲了映射到/從數據庫而獲取的元數據被緩存 - 因此只需要計算一次(這會大大提高性能)。

但是我所描述的性能平均值是多少?我無法想象用12秒來執行一個簡單的查詢是Entity Framework團隊可以接受的。我誤解他了嗎?元數據緩存是否在例如IIS應用程序池的整個生命週期中保持不變?這可能在某種程度上是可以接受的,儘管仍然不夠理想。

如果我不是先使用代碼,那麼我將能夠use EdmGen.exe to generate my views,據我瞭解,這將使我的應用程序更快。使用代碼首先開發我的模型時,是否有相同的方法?

更新2012年2月14日:感謝Pawel's post,我能夠產生我的意見。不幸的是,這並沒有改變創建一個新的PortalDatabase實例的速度,它仍然需要相同的時間。我知道正在使用視圖,因爲我在構造函數中放置了一個斷點,但這不影響任何內容。

+0

元數據高速緩存在* AppDomain *的生命週期中存在。元數據加載速度很慢,但對於這樣一個簡單的模型,12秒真的很慢。 – Slauma 2012-02-14 19:52:50

+0

我已將模型複製到控制檯應用程序中,創建空數據庫(由EF自動創建)。第一個查詢花了1秒,第二個查詢立即返回。這12秒很奇怪... – Slauma 2012-02-14 20:06:58

回答

2

使用CodeFirst生成視圖使用EF Power Tools。在此處查看更多詳細信息:http://blogs.msdn.com/b/adonet/archive/2011/05/18/ef-power-tools-ctp1-released.aspx

+0

非常感謝!我能夠產生的意見,但不幸的是這並沒有影響任何東西。你有什麼進一步的想法? – 2012-02-14 12:26:30

+0

你確定需要什麼時間?它只是第一個查詢還是所有查詢都很慢?如果僅僅是查詢,它可能最有可能是以下兩件事之一 - 視圖生成(不應該發生在小模型上)或者創建數據庫(如果不存在的話)。數據庫存在時你看到緩慢嗎?另外,你是否嘗試手動連接到數據庫?速度快嗎?如果所有查詢都發生這種情況 - 您是否可以嘗試使用Sql Profiler來查看執行查詢需要多長時間?你還使用任何更高級的映射,如層次結構或實體分割? – Pawel 2012-02-14 21:36:56

+0

如果你的模型和上面一樣簡單,你不應該期望EF/CodeFirst有太多的性能下降。對於這種模型,我會看看網絡/分貝。 – Pawel 2012-02-14 21:38:40