在Entity Framework Core中选择SelectMany + Select之后不能正常工作

Sup*_*JMN 3 c# entity-framework iqueryable entity-framework-core

我有使用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);
Run Code Online (Sandbox Code Playgroud)

该查询有效,但我得到的标题设置为标题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; }
}
Run Code Online (Sandbox Code Playgroud)

我需要做什么才能在返回的可查询中加载Translations?

Iva*_*oev 6

这是加载相关数据中描述的当前EF Core限制- 忽略包括:

如果更改查询以使其不再返回查询开头的实体类型的实例,则忽略包含运算符.

据此,您需要从中启动查询context.Set<TitleInformation>().但为了产生所需的过滤,你就需要反向导航属性TitleInformation,以Book目前的模型中的缺失:

class TitleInformation
{
    // ...
    public Book Book { get; set; } // add this and map it properly with fluent API
}
Run Code Online (Sandbox Code Playgroud)

一旦你拥有它,你可以使用这样的东西:

var titlesOwnedByUser = context.Set<TitleInformation>()
    .Include(ti => ti.Title)
        .ThenInclude(n => n.Translations)
    .Where(ti => ti.Book.Owners.Any(bu => bu.UserId == userId));
Run Code Online (Sandbox Code Playgroud)

或者,在壳体之间的关系TitleInformationBook是一个一对多(以上为一对的一个):

class TitleInformation
{
    // ...
    public List<Book> Books { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

分别为:

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));
Run Code Online (Sandbox Code Playgroud)