2012-02-13 30 views
3

広範囲にわたるグーグルグーグルから、私はこの問題に遭遇する最初の人ではないようだが、満足に解決できる人を見つけることができなかった。従来のデータベースを使用していましたが、(現時点で)単一のテーブルに統合しようとしていますが、このモデルへの最初のクエリでは約12秒かかります。 2番目の呼び出しは、予想どおりほとんど瞬間です。このコードサンプルは8-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"); 
    } 
} 

を実行するために:私は、この問題を行うことであることを理解し

PortalDatabase database = new PortalDatabase(); 

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

次の何

は私のEntity Frameworkのコードファースト・セットアップの全体ですは「パフォーマンスを大幅に向上させる」というメタデータの生成を1度だけ実行します。

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

+0

モデルをコンソールアプリケーションにコピーしました。空のデータベースが作成されました(EFによって自動的に作成されました)。最初のクエリに1秒かかり、2番目のクエリがすぐに返されました。これらの12秒は奇妙です... – Slauma

答えて

2

CodeFirstでビューを生成するには、EF Power Toolsを使用します。詳細はこちら:http://blogs.msdn.com/b/adonet/archive/2011/05/18/ef-power-tools-ctp1-released.aspx

+0

ありがとう!私はビューを生成することができたが、残念ながらこれは何も影響を受けていない。それ以上のアイデアはありますか? –

+0

あなたは時間がかかることを確認しましたか?最初のクエリか、すべてのクエリが遅いのですか?単なるクエリの場合は、ビューの生成(小さなモデルでは発生しない)と存在しない場合のデータベースの作成の2つのうちの1つです。データベースが存在するときに遅さが分かりますか?また、手動でデータベースに接続しようとしましたか?それは速かったか?これがすべてのクエリで発生した場合、Sql Profilerを使用してクエリを実行するのにかかる時間を確認できますか?また、階層やエンティティ分割などの高度なマッピングを使用していますか? – Pawel

+0

あなたのモデルが上記のような単純なものであれば、EF/CodeFirstのパフォーマンス低下はあまり期待できません。この種のモデルの場合、私はnetwork/dbを見ます。 – Pawel

関連する問題