简体   繁体   English

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

[英]How to include related tables in DbSet.Find()?

If I want to include related objects in an EF7 query, it's nice and easy: 如果我想在EF7查询中包括相关对象,那就好又容易:

var myThing = db.MyThings
                .Include(t => t.RelatedThing)
                .Where(t => t.SomeCondition == true)
                .ToList();

Also, there's a nice method on the DbSet<T> that makes it easy to load a single object by its key: 另外, DbSet<T>上有一个不错的方法,可以很容易地通过其键加载单个对象:

var myThing = db.MyThings.Find(thingId);

But now I want to load myThing by its Id, along with its RelatedThing . 但是现在,我想按其ID加载myThing以及RelatedThing Unfortunately (and understandably) .Find() is a method of DbSet<T> , not IQueryable<T> . 不幸的是(并且可以理解) .Find()DbSet<T>的方法,而不是IQueryable<T> Obviously I could do this: 显然我可以这样做:

var myThing = db.MyThings
                .Include(t => t.RelatedThing)
                .SingleOrDefault(t => t.MyThingId == thingId);

But I specifically want to use the .Find() method, because it's nice and generic and I'm writing a method that generically loads a record along with "included" relationships specified by an Expression<Func<T, object>> . 但是我特别想使用.Find()方法,因为它很好且通用,并且我正在编写一种方法,该方法通常将记录与由Expression<Func<T, object>>指定的“包含”关系一起加载。

Any suggestions how to do this? 有什么建议怎么做?

Use Find, in combination with Load, for explicit loading of related entities. 与查找结合使用查找,可以显式加载相关实体。 Below a MSDN example: 在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(); 
}

here is MSDN link 这是MSDN链接

It was not possible with EF6, I don't think EF Core will change that. EF6是不可能的,我认为EF Core不会改变这一点。 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. 这是因为Find方法的主要目的是从本地缓存中获取已经加载的实体,如果不存在,则从数据库中加载它。 So the eager loading ( Include ) can be used only in the later case, while in the former it would need to perform explicit loading. 因此,紧急加载( Include )只能在后一种情况下使用,而在前一种情况下,则需要执行显式加载。 Combining both in a single method might be technically possible, but is hard. 在技​​术上可以将两种方法组合在一起,但是很难。

I think you should take the FirstOrDefault (or SingleOrDefault ) route combined with eager loading. 我认为您应该将FirstOrDefault (或SingleOrDefault )路由与急切的加载结合使用。 You can see a sample implementation for EF6 in Repository generic method GetById using eager loading . 您可以使用急切加载存储库通用方法GetById中看到EF6的示例实现。 It could be adjusted for EF Core like using the dbContext.Model.FindEntityType(typeof(T)).FindPrimaryKey().Properties to find the PK properties and build the predicate. 可以使用dbContext.Model.FindEntityType(typeof(T)).FindPrimaryKey().Properties来针对EF Core进行调整,以查找PK属性并构建谓词。 Also since EF Core includes are bit more complicated (require Include / ThenInclude chains), you might find interesting this thread Can a String based Include alternative be created in Entity Framework Core? 另外,由于EF Core包含要复杂一些(需要Include / ThenInclude链),所以您可能会发现此线程有趣。 可以在Entity Framework Core中创建基于字符串的Include替代项吗? .

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM