0

Eager Loadingを使用して置き換える方法はLazy loading?

このように言いましょう。私は以下の種類のEFクエリをたくさん持っています。パフォーマンスに関しては、Include keysこれは非常に遅いです。

では、以下のコードを使用してパフォーマンスを向上させるにはどうすればよいLazy loadingですか?

from owner in Catalog.Owners
            where owner.Key == ownerKey
            from invoice in owner.Invoices
            where invoice.Provider.Key == providerKey
            where invoice.Id == id
            select invoice)
            .Include(i => i.Owner.Credits)
            .Include(i => i.Provider)
            .Include(i => i.Items.Select(s => s.Allocation.Service))
            .Include(i => i.Items.Select(s => s.Allocation.Pet))
            .FirstOrDefault();

サンプルコードの説明をいただければ完璧です。

4

2 に答える 2

2

EF 4.1 以降では、コード ファースト ナビゲーション プロパティ (他のエンティティにリンクするプロパティ) を として定義する必要がありますvirtual。次に、 内にいるDbContext場合、リンクされたエンティティは、実際に使用されるとき (遅延ロード) にのみデータベースからクエリされます。

ただし、すべてのデータをすぐに取得したい場合は、熱心な読み込みが使用されます。通常、これには正当な理由があります。したがって、最初に言いたいのは、熱心な読み込みを行う理由がわからない場合は、それを行うべきではないということです。エンティティをリンクするプロパティが仮想であることを確認してから.Include、クエリ内のステートメントを削除してください。

ただし、クエリ対象のデータを外部で取得する場合、DbContextまたはデータをすぐに使用する場合は、操作中にそのデータをメモリにプルするのが理にかなっています。

ですから、あなたの質問に答えて、単にeagerローディングをlazyローディングに置き換えるだけであるとは限りません。クエリが実行されたデータに対して何が行われているかを確認し、必要な最小限のセットのみを返す方法を確認する必要があります。

追加された例:

    public class Person
    {
        public int Id { get; set; }
        public string Name { get; set; }

        public virtual ICollection<Car> Cars { get; set; } //make it virtual

    }

    public class Car
    {
        public int Id { get; set; }
        public string Make { get; set; }
        public string Model { get; set; }
    }

    public class MyContext : DbContext
    {
        public IDbSet<Person> People { get; set; }
        public IDbSet<Car> Cars { get; set; }
    }

    class Program
    {
        private static void Main(string[] args)
        {
            using (var context = new MyContext())
            {
                var person = context.People.FirstOrDefault(p => p.Id == 1); // calls the database

                var car = person.Cars.FirstOrDefault(c => c.Id == 2); // Lazy loads Cars

            }
        }
    }
于 2013-01-20T19:58:06.923 に答える
2

積極的な読み込み (Include呼び出し) を使用しない場合、すべてが正しく設定されていれば、遅延読み込みが自動的に使用されます。

  • virtualナビゲーション プロパティ
  • 遅延読み込みとプロキシ作成が許可されています (デフォルトである必要があります)
  • ルート オブジェクトの読み込みに使用されるオブジェクト コンテキストのスコープで実行される遅延読み込み

遅延読み込みは、ナビゲーション プロパティにアクセスする場合にのみ、関連するエンティティを読み込むクエリを実行するため、たとえば、すべての関連データが常に必要なわけではない場合はパフォーマンスが向上しますが、常に必要な場合は、パフォーマンスがさらに低下する可能性があります。多くのデータベース往復。

于 2013-01-20T19:58:25.767 に答える