2013-04-22 18 views
5

私はEFクエリで少しのパフォーマンス上の問題があります。問題は、私が集めることができるものから、これは最初にフェッチされるリスト全体を引き起こし、ということである最も効率的な方法でレイジーリストのカウントを取得するには?

Article a = ...; 
vm.Count = a.Visits.Count; 

public class Article 
{ 
    public int ID { get; set; } 
    public virtual List<Visit> Visits { get; set; } 
} 
public class Visit 
{ 
    public int? ArticleID { get; set; } 
    public DateTime Date { get; set; } 
} 

さて、私がやりたい:

私たちは、基本的にこれを持っています、そしてそれの数。これをループで実行すると、パフォーマンス上の問題が発生します。

オブジェクトが「あまりにも具体的」であると想定していたので、Visits.Countコールをできるだけリポジトリに戻して移動しようとしました(つまり、私たちはDbContext )。それは役に立たなかった。

提案がありますか?

+0

記事に「GetVisitsCount」を追加できますか? - あなたがそれを使用することにどれくらいの時間を要しているのか、数回だけであればパフォーマンスの問題はそれほどありませんので、私はかなり多くを推測しています。 – Sayse

答えて

0

が訪問プロパティを持っています

public class MyDbContext: DbContext 
{ 
    public IDbSet<Article> Articles { get; set; } 
    public IDbSet<Visit> Visits { get; set; } 
} 

あなたがそれを行うことができ記事を扱うときに必ずしも必要ではありません。IEnumerable<T>

public class Article 
{ 
    public int ID { get; set; } 
    public virtual IEnumerable<Visit> Visits { get; set; } 
} 

そして遅延ロードに依存しています。

+0

これは今までのところ最善の策だと思っています。私は似たようなことをしましたが、訪問と記事の間で参加しました。 – NiklasJ

+0

これを解決策または鉱山としてマークする必要があるかどうかはわかりません。これはより良いですが、私はそれをやった方法ではありません。 IEnumerableの "トリック"はうまくいかないようでしたが、ICollectionを使用しなければなりませんでした。 – NiklasJ

0

パフォーマンスの問題は遅延ロードにあると思います。 (しかし、それ以上のコードを見る必要があります)。

dbcontextから記事を取得した時点でインクルード(a => a.Visits)を試してください。 EFのパフォーマンスに多くのinforamtionのため

:訪問のコレクションがある場合も

using (var ctx = new MyDbContext()) 
{ 
    var count = ctx.Visits.Where(x => x.ArticleID == 123).Count(); 
} 

:あなたのデータコンテキストを想定しhttp://www.asp.net/web-forms/tutorials/continuing-with-ef/maximizing-performance-with-the-entity-framework-in-an-asp-net-web-application

+0

私はこれを試しましたが、私はまだこの種の巨大なリストの「具体化」が問題だと思っており、これはちょっと前に評価をプッシュするだけです。 – NiklasJ

0

私はそれを別の方法でやりました。

私はこれはさまざまな方法で何度も見舞われたことがわかった、とによるドメインモデルの残りの部分が設定されているような方法で、私はハックのビットを作った:

私VisitRepositoryでは、私が作成しました新しい関数GetArticleIDsWithVisit()は、db.SqlQueryを介して直接SQL呼び出しを行い、辞書を返します。辞書はキャッシュされ、訪問回数が必要なすべての場所で使用されます。

私はそれが大丈夫だと思うので、あまりにもかわいいですが、私はリポジトリの中にそれをラップしました。

関連する問題