[英]How to include related tables in DbSet.Find()?
如果我想在EF7查询中包括相关对象,那就好又容易:
var myThing = db.MyThings
.Include(t => t.RelatedThing)
.Where(t => t.SomeCondition == true)
.ToList();
另外, DbSet<T>
上有一个不错的方法,可以很容易地通过其键加载单个对象:
var myThing = db.MyThings.Find(thingId);
但是现在,我想按其ID加载myThing
以及RelatedThing
。 不幸的是(并且可以理解) .Find()
是DbSet<T>
的方法,而不是IQueryable<T>
。 显然我可以这样做:
var myThing = db.MyThings
.Include(t => t.RelatedThing)
.SingleOrDefault(t => t.MyThingId == thingId);
但是我特别想使用.Find()
方法,因为它很好且通用,并且我正在编写一种方法,该方法通常将记录与由Expression<Func<T, object>>
指定的“包含”关系一起加载。
有什么建议怎么做?
与查找结合使用查找,可以显式加载相关实体。 在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();
}
这是MSDN链接
EF6是不可能的,我认为EF Core不会改变这一点。 这是因为Find
方法的主要目的是从本地缓存中获取已经加载的实体,如果不存在,则从数据库中加载它。 因此,紧急加载( Include
)只能在后一种情况下使用,而在前一种情况下,则需要执行显式加载。 在技术上可以将两种方法组合在一起,但是很难。
我认为您应该将FirstOrDefault
(或SingleOrDefault
)路由与急切的加载结合使用。 您可以使用急切加载在存储库通用方法GetById中看到EF6的示例实现。 可以使用dbContext.Model.FindEntityType(typeof(T)).FindPrimaryKey().Properties
来针对EF Core进行调整,以查找PK属性并构建谓词。 另外,由于EF Core包含要复杂一些(需要Include
/ ThenInclude
链),所以您可能会发现此线程很有趣。 可以在Entity Framework Core中创建基于字符串的Include替代项吗? 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.