如何在 EF 内核中调用两次 Then include?

我正在创建一个 ASP.NET Core API 应用程序,并依赖于 EF Core:

public class AppUser : IdentityUser
{
public string FirstName { get; set; }


public string LastName { get; set; }


[InverseProperty(nameof(Post.Author))]
public ICollection<Post> Posts { get; set; } = new List<Post>();
}


public class Post
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }


public string AuthorId { get; set; }


[ForeignKey("AuthorId")]
public virtual AppUser Author { get; set; }


[InverseProperty(nameof(Like.Post))]
public ICollection<Like> Likes { get; set; } = new List<Like>();


[InverseProperty(nameof(Comment.Post))]
public ICollection<Comment> Comments { get; set; } = new List<Comment>();
}

其中 CommentLike是其他一些实体。请注意,为了简洁起见,我已经简化了实体。然后,我想得到一个用户的 Posts,但也包括 LikesComments,一个帖子已经得到。所以,我做了这样的事情:

return _context.Users
.Include(u => u.Location)
.Include(u => u.Posts)
.ThenInclude(p => p.Comments)
.ThenInclude(c => c.Owner)
.Include(u => u.Posts)
.ThenInclude(p => p.Likes)
.ThenInclude(l => l.Giver)
.Where(u => u.Id == userId)
.FirstOrDefault();

现在,这个工作正常,但你可以看到,我正在呼叫 .Include(u = u.Posts)两次。有没有一种方法可以在同一属性上调用 ThenInclude两次,而不必实际写入 Include语句也两次?

48988 次浏览

Now, this works fine, but as you can see I'm calling .Include(u = u.Posts) twice. Is there a way to call ThenInclude twice on same property, without actually writing the Include statement also twice?

Calling Include(u => u.Posts) twice is the right way to do it.

From EF Core docs... emphasis on the last sentence.

You may want to include multiple related entities for one of the entities that is being included. For example, when querying Blogs, you include Posts and then want to include both the Author and Tags of the Posts. To do this, you need to specify each include path starting at the root. For example, Blog -> Posts -> Author and Blog -> Posts -> Tags. This does not mean you will get redundant joins, in most cases EF will consolidate the joins when generating SQL.

using (var context = new BloggingContext())
{
var blogs = context.Blogs
.Include(blog => blog.Posts)
.ThenInclude(post => post.Author)
.Include(blog => blog.Posts)
.ThenInclude(post => post.Tags)
.ToList();
}

You cannot use ThenInclude with multiple navigation properties. You have to have Include.

Here is bug opened for this.