Help us understand the problem. What is going on with this article?

Entity Frameworkの関連のロード

以下のEntityでFoo.Barsのロードの説明。

public class SampleContext: DbContext
{
    public DbSet<Foo> Foos { get; set; }
    public DbSet<Bar> Bars { get; set; }
}

public class Foo
{
    public long Id { get; set; }
    public virtual ICollection<Bar> Bars { get; set; }
}

public class Bar
{
    public long Id { get; set; }
    public long FooId { get; set; }
    [ForeignKey("FooId")]
    public virtual Foo Foo { get; set; }
}

LazyLoading

LazyLoadingEnabledがtrue

はじめてのfoo.Barsアクセス時にLazyロードが走ります。
LazyLoadingEnabledはtrueがデフォルト。

var foo = default(Foo);
using (var context = new SampleContext())
{
    foo = context.Foos.Where(f => f.Id == 1).Single();
    var bars1 = foo.Bars; // ここでLazyロード
}
var bar2 = foo.Bars; // いったんロードされているのでちゃんと取れる
var foo = default(Foo);
using (var context = new SampleContext())
{
    foo = context.Foos.Where(f => f.Id == 1).Single();
}
// contextは破棄されているのにここでLazyロードしようとしてObjectDisposedException
var bars = foo.Bars;

LazyLoadingEnabledがfalse

var foo = default(Foo);
using (var context = new SampleContext())
{
    context.Configuration.LazyLoadingEnabled = fales;
    foo = context.Foos.Where(f => f.Id == 1).Single();
    var bars = foo.Bars; // Lazyロードされずにbarsはnull
}
var foo = default(Foo);
using (var context = new SampleContext())
{
    context.Configuration.LazyLoadingEnabled = fales;
    foo = context.Foos.Where(f => f.Id == 1).Single();
}
var bars = foo.Bars; // Lazyロードされずにbarsはnull

明示的にロード

明示的にロードしておけばcontext.Configuration.LazyLoadingEnabledにかかわらずcontext内外でBarsを読めます。

Include()

Include()を使うとFooとBarをまとめてロードできます。
基本的には処理に必要な関連はInclude()で一気にロードしておくべきです。
Include()はcontext.Foos.Include(f => f.Bars).Include(f => f.AnotherAssoc)のようにつなげて書けます。

var foo = default(Foo);
using (var context = new SampleContext())
{
    // ここでロード
    foo = context.Foos.Include(f => f.Bars).Where(f => f.Id == 1).Single();

    var bars1 = foo.Bars; // 普通に取れる
}
var bars2 = foo.Bars; // 普通に取れる

Load()

Load()を使うとBarを個別にロードできます。
Fooのロード量が多く、かつ、Barsをロードする必要があるFooは少量なときは、
Include()よりLoad()またはLazyロードに任せるのがいいです。

var foo = default(Foo);
using (var context = new SampleContext())
{
    foo = context.Foos.Where(f => f.Id == 1).Single();

    context.Entry(foo).Collection(f => f.Bars).Load(); // ここでロード

    var bars1 = foo.Bars; // 普通に取れる
}
var bars2 = foo.Bars; // 普通に取れる
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした