如何在 EF Core 中调用 ThenInclude 两次?

Posted

技术标签:

【中文标题】如何在 EF Core 中调用 ThenInclude 两次?【英文标题】:How to call ThenInclude twice in EF Core? 【发布时间】:2018-11-26 14:26:02 【问题描述】:

我正在创建一个 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 语句?

【问题讨论】:

【参考方案1】:

现在,这很好用,但正如您所见,我调用了 .Include(u = u.Posts) 两次。有没有办法在同一个属性上调用 ThenInclude 两次,而不用实际编写 Include 语句两次?

拨打Include(u =&gt; u.Posts) 两次是正确的做法。

来自EF Core docs...强调最后一句。

您可能希望为要包含的实体之一包含多个相关实体。例如,在查询Blogs 时,您包含Posts,然后想同时包含PostsAuthorTags。为此,您需要指定从根开始的每个包含路径。例如,Blog -&gt; Posts -&gt; AuthorBlog -&gt; Posts -&gt; Tags这并不意味着您将获得冗余连接,在大多数情况下,EF 会在生成 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();

【讨论】:

现在是微软实施AlsoInclude() 的好时机,以防止您不得不多次编写相同的包含语句 我在不知道不存在的情况下输入了 AlsoInclude!!【参考方案2】:

您不能将ThenInclude 与多个导航属性一起使用。你必须有Include

这是为此打开的bug。

【讨论】:

我注意到在 Include 中指定完整路径也可以,例如Include(u => u.Posts) .Include(u => u.Posts.Comments) 这是等价的吗?有什么缺点吗?

以上是关于如何在 EF Core 中调用 ThenInclude 两次?的主要内容,如果未能解决你的问题,请参考以下文章

[小技巧]EF Core中如何获取上下文中操作过的实体

EF Core 调用具有多个连接的存储过程并映射相关数据

如何在 EF Core 3.1 中使用脚手架流程更新我的实体 - 执行超时已过期

如何在 .net core ef 上应用 thenInclude 条件?

EF Core 调用 INSERT 而不是 UPDATE

.net core EF Core 视图的应用