如果我想在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>>
方法,因为它很好且通用,而且我正在编写一个通常加载记录的方法以及{
"result": 0,
"metadata": [
],
"checksums": [
],
"fileids": [
]
}
指定的“包含”关系。 / p>
有任何建议怎么做?
答案 0 :(得分:5)
将Find与Load结合使用,以显式加载相关实体。 在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 link
答案 1 :(得分:2)
EF6无法实现,我认为EF Core不会改变它。这是因为Find
方法的主要目的是从本地缓存中引入已加载的实体,或者如果不存在则从数据库加载它。因此,急切加载(Include
)只能在后一种情况下使用,而在前者中则需要执行显式加载。将这两种方法结合在一起可能在技术上是可行的,但很难。
我认为您应该将FirstOrDefault
(或SingleOrDefault
)路线与急切加载相结合。您可以在Repository generic method GetById using eager loading中查看EF6的示例实现。可以使用dbContext.Model.FindEntityType(typeof(T)).FindPrimaryKey().Properties
来调整EF Core,以查找PK属性并构建谓词。此外,由于EF Core包含的内容有点复杂(需要Include
/ ThenInclude
个链),您可能会发现这个帖子Can a String based Include alternative be created in Entity Framework Core?很有意思。