web-dev-qa-db-fra.com

Comment appeler ThenInclude deux fois dans EF Core?

Je crée une application API ASP.NET Core et je m'appuie sur EF Core. J'ai des entités définies comme ceci:

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 et Like sont quelques autres entités. Veuillez noter que j'ai simplifié les entités par souci de concision. Ensuite, je veux obtenir le Posts d'un utilisateur, mais aussi inclure le Likes et Comments qu'un message a obtenu. J'ai donc fait quelque chose comme ça:

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();

Maintenant, cela fonctionne très bien, mais comme vous pouvez le voir, j'appelle deux fois .Include(u = u.Posts). Existe-t-il un moyen d'appeler ThenInclude deux fois sur la même propriété, sans réellement écrire deux fois l'instruction Include?

11
tinker

Vous ne pouvez pas utiliser ThenInclude avec plusieurs propriétés de navigation. Vous devez avoir Include.

Voici bug ouvert pour cela.

7
vivek nuna

Maintenant, cela fonctionne bien, mais comme vous pouvez le voir, j'appelle .Include (u = u.Posts) deux fois. Existe-t-il un moyen d'appeler ThenInclude deux fois sur la même propriété, sans réellement écrire deux fois l'instruction Include?

Appeler Include(u => u.Posts) deux fois est la bonne façon de procéder.

De EF Core docs ... accent sur la dernière phrase.

Vous souhaiterez peut-être inclure plusieurs entités liées pour l'une des entités qui est incluse. Par exemple, lorsque vous interrogez Blogs, vous incluez Posts et souhaitez ensuite inclure à la fois Author et Tags de Posts. Pour ce faire, vous devez spécifier chaque chemin d'inclusion à partir de la racine. Par exemple, Blog -> Posts -> Author et Blog -> Posts -> Tags. Cela ne signifie pas que vous obtiendrez des jointures redondantes, dans la plupart des cas, EF consolidera les jointures lors de la génération de 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();
}
34
Jan Paolo Go