2011-06-24 12 views
8

私はEntity Framework Code Firstを使用していて、小さなロードブロックを実行していました。私が呼ぶとき、しかしエンティティフレームワークコードファーストIQueryable

public class History 
{ 
    public Guid Id { get; set; } 
    public virtual Person Owner { get; set; } 
    public DateTime OnDate { get; set; } 
} 

public class Person 
{ 
    public Guid Id { get; set; } 
    public virtual ICollection<History> History { get; set; } 
} 

、そのように定義したクラス "歴史":私はそのように定義クラス "人" を持っている

IEnumerable<History> results = person.History 
           .OrderBy(h => h.OnDate) 
           .Take(50) 
           .ToArray(); 

それが表示されますその人のためにすべての歴史を引っ張って、それをメモリに注文する。私が逃しているものについての推奨事項はありますか?

ありがとうございます!

+0

あなたはどのような動作を期待していましたか?結果を50レコードに限定することはできませんか? –

+3

私は期待された動作がデータベースでそれを注文することだと思います –

+1

私はそれが注文を送信し、サーバーに制限することを期待していたので、SQLサーバーは注文と制限を行いました。代わりに、すべての履歴をメモリに保存し、その連絡先のすべての30,000以上の要素を確認してから、メモリ内で注文と制限を行います。 – Terry

答えて

5

IEnumerable(つまり:LINQ to Objects)は、IQueryable(つまり、LINQ to Entities)ではなくEFによって指定されているためです。

代わりに、

IEnumerable<History> results = context.History.Where(h => h.Person.Id = "sfssd").OrderBy(h => h.OnDate).Take(50) 
+0

これはEFコードです。まず、 'Person'がDBから取得されたと想定されます。そのため、ナビゲーションプロパティ' History'がコンテキストに接続されています。 – BrokenGlass

+0

@BrokenGlassはいそれは接続されています。しかし、タイプ 'ICollection 'は 'IQueryable 'ではありません。したがって、 'person.History'にアクセスすると、すべてのヒストリオブジェクトをロードします。 – Eranga

+0

ああ、怠惰な読み込みが始まり、完全なコレクションを読み込むので、もちろん正しいです。私の+1を得た – BrokenGlass

0

この質問と受け入れ答えは両方とも少し古いです使用する必要があります。このようなコードは、元々の質問ポイントとして、データベースの人物全体の履歴を読み込みます。

var results = person 
    .History 
    .OrderBy(h => h.OnDate) 
    .Take(50) 
    .ToArray(); 

EF 6で簡単な解決策があります。クエリを並べ替えることなく、DbContext.Entry methodDbEntryEntity.Collection method、およびDbCollectionEntry.Query methodを使用して、クエリをIQueryableの方法で処理させることができます。

var results = dbContext 
    .Entry(person) 
    .Collection(p => p.History) 
    .Query() 
    .OrderBy(h => h.OnDate) 
    .Take(50) 
    .ToArray(); 
関連する問題