在 Entity Framework Core 中,使用 SelectMany 和 Select 后,“Include” 不起作用

7

我有一个使用Entity Framework Core (v2)的查询,但是Include/ThenInclude不像我预期的那样工作。以下是查询:

 var titlesOwnedByUser = context.Users
                   .Where(u => u.UserId == userId)
                   .SelectMany(u => u.OwnedBooks)
                   .Select(b => b.TitleInformation)
                   .Include(ti => ti.Title)
                   .ThenInclude(n => n.Translations);

这个查询是有效的,但我得到的标题是 null

为了澄清,这些类是这些

class User 
{
     public int Id { get; set; }
     public List<BookUser> OwnedBooks { get; set; }
}

class Book 
{
    public int Id { get; set; }
    public TitleInformation TitleInformation { get; set; }
    public List<BookUser> Owners { get; set; }
}

class BookUser 
{
     public int BookId { get; set; }
     public int UserId { get; set; }
     public Book Book { get; set; }
     public User User { get; set; }
}

class MyContext
{
     protected override void OnModelCreating(ModelBuilder modelBuilder)
     {
        modelBuilder.Entity<BookUser>()
            .HasOne(x => x.User)
            .WithMany(x => x.OwnedBooks)
            .HasForeignKey(x => x.UserId);

        modelBuilder.Entity<BookUser>()
            .HasOne(x => x.Book)
            .WithMany(x => x.Owners)
            .HasForeignKey(x => x.BookId);
     }
}

class TitleInformation
{
    public int Id { get; set; }
    public Title Title { get; set; }
    public Title Subtitle { get; set; }
}

class Title
{
     public int Id { get; set; }
     public string OriginalTitle { get; set; }
     public List<Translation> Translations { get; set; }
}

我需要做什么才能使翻译在返回的可查询结果中加载?

你能展示一下实体的配置吗? - H. Herzl
听起来像是忽略的包含。你应该从context.TitleInformation开始构建查询,换个方式来做。 - Ivan Stoev
@H.Herzl请查看原帖更新。 - SuperJMN
@IvanStoev 我该如何开始呢?你能否提供一下代码吗?我有点迷失 :( - SuperJMN
可能是Entity Framework Core SelectMany then Include的重复问题。 - animalito maquina
1个回答

9
这是描述在加载相关数据-忽略包含中的当前EF Core限制:
如果更改查询,使其不再返回查询开始时的实体类型的实例,则包括运算符将被忽略。
根据这个描述,你需要从context.Set<TitleInformation>()开始查询。但为了产生所需的筛选结果,你需要从TitleInformationBook的逆向导航属性,目前此属性在你的模型中缺失。
class TitleInformation
{
    // ...
    public Book Book { get; set; } // add this and map it properly with fluent API
}

一旦你拥有它,你可以使用类似这样的东西:
var titlesOwnedByUser = context.Set<TitleInformation>()
    .Include(ti => ti.Title)
        .ThenInclude(n => n.Translations)
    .Where(ti => ti.Book.Owners.Any(bu => bu.UserId == userId));

或者,如果TitleInformationBook之间的关系是一对多(上述内容是针对一对一关系的):
class TitleInformation
{
    // ...
    public List<Book> Books { get; set; }
}

分别为:

var titlesOwnedByUser = context.Set<TitleInformation>()
    .Include(ti => ti.Title)
        .ThenInclude(n => n.Translations)
    .Where(ti => ti.Books.SelectMany(b => b.Owners).Any(bu => bu.UserId == userId));

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接