Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to call ThenInclude twice in EF Core?

I'm creating an ASP.NET Core API app, and relying on EF Core. I have entities defined like this:

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

Where Comment and Like are some other entities. Please note that I have simplified the entities for brevity. Then, I want to get the Posts of a user, but also include the Likes and Comments that a post has gotten. So, I did something like this:

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

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?

like image 780
tinker Avatar asked Jun 17 '18 14:06

tinker


People also ask

How do you create a one to many relationship in EF core?

The easiest way to configure a one-to-many relationship is by convention. EF Core will create a relationship if an entity contains a navigation property. Therefore, the minimum required for a relationship is the presence of a navigation property in the principal entity: public class Author.

How do I debug EF core query?

For use this, you're going to want to set a breakpoint below your EF Core query. Breakpoint hit after the query. Once the breakpoint is hit hover over query to expand then click on > Debug View > The dropdown beside the magnifying glass> Text Visualizer. There you have it, the SQL that will be sent to the database.

Does EF core cache query results?

Using Caching in Entity Framework Core. NCache provides integration for caching in Entity Framework Core through Extension Methods. You can cache the result sets of LINQ queries whether they are for transactional data or reference data.


2 Answers

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(); } 
like image 89
Jan Paolo Go Avatar answered Oct 08 '22 05:10

Jan Paolo Go


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

Here is bug opened for this.

like image 45
vivek nuna Avatar answered Oct 08 '22 04:10

vivek nuna