関連するオブジェクトをEF7クエリに含める場合は、すばらしく簡単です。
var myThing = db.MyThings
.Include(t => t.RelatedThing)
.Where(t => t.SomeCondition == true)
.ToList();
また、 DbSet<T>
には、単一のオブジェクトをそのキーで簡単に読み込むための便利なメソッドがあります。
var myThing = db.MyThings.Find(thingId);
しかし、今、私はロードしたいmyThing
そのとともに、そのIdでRelatedThing
。残念なことに(わかりやすく) .Find()
は、 IQueryable<T>
ではなく、 DbSet<T>
メソッドです。明らかに私はこれを行うことができます:
var myThing = db.MyThings
.Include(t => t.RelatedThing)
.SingleOrDefault(t => t.MyThingId == thingId);
しかし、私は具体的には.Find()
メソッドを使いたいと思っています。なぜなら、それは汎用的で一般的なので、 Expression<Func<T, object>>
指定された "インクルード"関係とともにレコードを一般にロードするメソッドを作成しているからです。
どのようにこれを行うための任意の提案?
EF6では可能ではありませんでしたが、EF Coreがそれを変更するとは思いません。これは、 Find
メソッドの主な目的は、既にロードされたエンティティをローカルキャッシュから取得すること、または存在しない場合はデータベースからロードすることです。したがって、熱心な読み込み( Include
)は後者の場合にのみ使用でき、前者では明示的な読み込みを実行する必要があります。単一の方法で両方を組み合わせることは、技術的に可能かもしれませんが、難しいです。
私はFirstOrDefault
(またはSingleOrDefault
)ルートと熱心なロードを組み合わせるべきだと思います。 熱心な読み込みを使用して 、 リポジトリジェネリックメソッドGetByIdでEF6のサンプル実装を見ることができます。これは、 dbContext.Model.FindEntityType(typeof(T)).FindPrimaryKey().Properties
ようにEF Coreのために調整することができますdbContext.Model.FindEntityType(typeof(T)).FindPrimaryKey().Properties
PK dbContext.Model.FindEntityType(typeof(T)).FindPrimaryKey().Properties
を見つけて述語を構築するためのプロパティ。また、EFコアのインクルードは少し複雑です( Include
/ ThenInclude
チェーンが必要です)。興味深いこのスレッドが見つかりましたThenInclude
FrameworkコアでStringベースのインクルードの代替案を作成できますか? 。
関連するエンティティを明示的に読み込むには、「読み込み」と組み合わせて「検索」を使用します。 MSDNの例の下:
using (var context = new BloggingContext())
{
var post = context.Posts.Find(2);
// Load the blog related to a given post
context.Entry(post).Reference(p => p.Blog).Load();
// Load the blog related to a given post using a string
context.Entry(post).Reference("Blog").Load();
var blog = context.Blogs.Find(1);
// Load the posts related to a given blog
context.Entry(blog).Collection(p => p.Posts).Load();
// Load the posts related to a given blog
// using a string to specify the relationship
context.Entry(blog).Collection("Posts").Load();
}