Reputation: 6347
I have the following schema:
public class Post {
public string Id {get;set;}
public string Content {get;set;}
public AppUser AppUser {get;set;}
public List<PostTag> PostTags {get;set;}
}
public class Tag {
public string Id {get;set;}
public string Name {get;set;}
public List<PostTag> PostTags {get;set;}
}
public class PostTag
{
public string PostId { get; set; }
public Post Post { get; set; }
public string TagId { get; set; }
public Tag Tag { get; set; }
}
With the following db relationships:
builder.Entity<PostTag>()
.HasKey(x => new { x.PostId, x.TagId });
builder.Entity<PostTag>()
.HasOne(st => st.Post)
.WithMany(s => s.PostTags)
.HasForeignKey(st => st.PostId);
builder.Entity<PostTag>()
.HasOne(st => st.Tag)
.WithMany(s => s.PostTags)
.HasForeignKey(st => st.TagId);
I'm writing a query to get all the Posts that are linked to a specific Tag, based on the provided TagId.
First I get all the posts using:
var postsQuery = _ctx.PostTag
.Include(st => st.Post)
.Where(st => st.TagId == {provided TagId})
.Select(st => st.Post);
Since I want to include some further data to each post, I do:
var postsWithExtraData = postsQuery
.Include(s => s.AppUser)
.Include(s => s.PostTags)
.ThenInclude(st => st.Tag)
.OrderByDescending(s => s.TotalVoteCount)
.ToListAsync();
But the query breaks on the first .Include
with this error:
EF Core “InvalidOperationException: Include has been used on non entity queryable”
Why is this happening and how can I fix it?
EDIT: Potential solution that I got to work:
var posts = _ctx.PostTag
.Include(st => st.Post)
.ThenInclude(s => s.AppUser)
.Include(st => st.Post)
.ThenInclude(s => s.PostTags)
.ThenInclude(st => st.Tag)
.Where(st => st.TagId == request.TagId)
.Select(st => st.Post)
.ToList();
Would love to know if this is a good approach or not.
Upvotes: 3
Views: 4825
Reputation: 12619
If you change the query so that it no longer returns instances of the entity type that the query began with, then the include operators are ignored.
So your code is giving error. You can do like below where you can use Includes
in your first query and use OrderByDescending
ToListAsync
to next.
var postsQuery = _ctx.PostTag
.Include(st => st.Post)
.ThenInclude(s => s.AppUser)
.Include(st => st.Post)
.ThenInclude(s => s.PostTags)
.ThenInclude(st => st.Tag)
.Where(st => st.TagId == {provided TagId})
.Select(st => st.Post);
var postsWithExtraData = postsQuery
.OrderByDescending(s => s.TotalVoteCount)
.ToListAsync();
Upvotes: 4
Reputation: 1141
First, you should write Include and ThenInclude
and then write your Condition
var postsWithExtraData = _ctx.PostTag
.Include(st => st.Post)
.Include(s => s.AppUser)
.Include(s => s.PostTags)
.ThenInclude(st => st.Tag)
.Where(st => st.TagId == {provided TagId})
.OrderByDescending(s => s.TotalVoteCount)
.ToListAsync();
Upvotes: 0