如何在DbSet.Find()中包含相关表?

Sha*_*ica 4 c# entity-framework-core

如果我想在EF7查询中包括相关对象,那就好又容易:

var myThing = db.MyThings
                .Include(t => t.RelatedThing)
                .Where(t => t.SomeCondition == true)
                .ToList();
Run Code Online (Sandbox Code Playgroud)

另外,有一个不错的方法DbSet<T>,可以轻松地通过其键加载单个对象:

var myThing = db.MyThings.Find(thingId);
Run Code Online (Sandbox Code Playgroud)

但是,现在我想myThing按其ID 加载它RelatedThing。不幸的是(并且可以理解).Find()是的一种方法DbSet<T>,不是IQueryable<T>。显然我可以这样做:

var myThing = db.MyThings
                .Include(t => t.RelatedThing)
                .SingleOrDefault(t => t.MyThingId == thingId);
Run Code Online (Sandbox Code Playgroud)

但是我特别想使用该.Find()方法,因为它既好又通用,并且我正在编写一种方法,该方法通常将记录与Expression<Func<T, object>>。指定的“包含”关系一起加载。

有什么建议怎么做?

小智 5

与查找结合使用查找,可以显式加载相关实体。在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(); 
}
Run Code Online (Sandbox Code Playgroud)

这是MSDN链接


Iva*_*oev 4

It was not possible with EF6, I don't think EF Core will change that. This is because the main purpose of the Find method is to bring the already loaded entity from the local cache, or load it from the database if it's not there. So the eager loading (Include) can be used only in the later case, while in the former it would need to perform explicit loading. Combining both in a single method might be technically possible, but is hard.

我认为你应该采取FirstOrDefault(或SingleOrDefault) 路线与急切加载相结合。您可以在存储库通用方法 GetById 中使用预加载查看 EF6 的示例实现。它可以针对 EF Core 进行调整,例如使用 来dbContext.Model.FindEntityType(typeof(T)).FindPrimaryKey().Properties查找 PK 属性并构建谓词。此外,由于 EF Core 包含有点复杂(需要Include/ThenInclude链),您可能会发现这个线程有趣:Can a String based Include replacement be create in Entity Framework Core?