简体   繁体   中英

EF Core “InvalidOperationException: Include has been used on non entity queryable” on IQueryable

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.

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM