我正在创建一个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>();
}
其中Comment
和Like
是其他实体。请注意,为简洁起见,我简化了实体。然后,我想获得用户的Posts
,还要包含帖子获得的Likes
和Comments
。所以,我做了类似的事情:
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
语句?
答案 0 :(得分:21)
现在,这样可以正常工作,但正如您所看到的那样,我会两次调用.Include(u = u.Posts)。有没有办法在同一个属性上调用ThenInclude两次,而没有实际写两次Include语句?
两次调用Include(u => u.Posts)
是正确的方法。
从EF Core docs ...强调最后一句话。
您可能希望为其中一个实体包含多个相关实体。例如,在查询
Blog
时,您包含Posts
,然后想要同时包含Author
的{{1}}和Tags
。为此,您需要指定从根开始的每个包含路径。例如,Posts
和Blog -> Posts -> Author
。 这并不意味着您将获得冗余连接,在大多数情况下,EF会在生成SQL时合并连接。
Blog -> Posts -> Tags
答案 1 :(得分:4)
您不能将ThenInclude
与多个导航属性一起使用。您必须拥有Include
。
这是为bug打开的。