EF Core «InvalidOperationException: Include было использовано для объекта, не запрашиваемого» в IQueryable - PullRequest
1 голос
/ 14 июля 2020

У меня есть следующая схема:

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

Со следующими отношениями db:

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

Я пишу запрос, чтобы получить все сообщения, которые связаны с определенным c Тег, основанный на предоставленном TagId.

Сначала я получаю все сообщения, используя:

var postsQuery = _ctx.PostTag
                    .Include(st => st.Post)
                    .Where(st => st.TagId == {provided TagId})
                    .Select(st => st.Post);

Поскольку я хочу добавить некоторые дополнительные данные в каждое сообщение, я делаю:

var postsWithExtraData = postsQuery
                            .Include(s => s.AppUser)
                            .Include(s => s.PostTags)
                            .ThenInclude(st => st.Tag)
                            .OrderByDescending(s => s.TotalVoteCount)
                            .ToListAsync();

Но запрос прерывается на первом .Include с этой ошибкой:

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

Почему это происходит и как я могу это исправить?

РЕДАКТИРОВАТЬ: Возможное решение, с которым я должен работать:

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

Хотелось бы узнать, хороший это подход или нет.

Ответы [ 2 ]

1 голос
/ 14 июля 2020

Если вы измените запрос так, чтобы он больше не возвращал экземпляры того типа сущности, который запрос начинается с , тогда операторы включения игнорируются.

Итак, ваш код дает ошибку. Вы можете сделать как показано ниже, где вы можете использовать Includes в своем первом запросе и использовать OrderByDescending ToListAsync для следующего.

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();
0 голосов
/ 14 июля 2020

Сначала вы должны написать Include and ThenInclude, а затем написать 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();
...