在实体框架核心中的 SelectMany + Select 之后“包含”不起作用
Posted
技术标签:
【中文标题】在实体框架核心中的 SelectMany + Select 之后“包含”不起作用【英文标题】:"Include" not working after SelectMany + Select in Entity Framework Core 【发布时间】:2018-05-11 18:34:45 【问题描述】:我使用 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;
我必须做些什么才能使返回的可查询的翻译加载?
【问题讨论】:
你能显示实体的配置吗? 听起来像Ignored includes。您应该以其他方式构建查询,从context.TitleInformation
开始。
@H.Herzl 请检查更新 OP。
@IvanStoev 我怎么知道如何开始?你能包括代码吗?我有点失落:(
Entity Framework Core SelectMany then Include的可能重复
【参考方案1】:
这是Loading Related Data - Ignored includes 中描述的当前 EF Core 限制:
如果您更改查询以使其不再返回查询开始时使用的实体类型的实例,则包含运算符将被忽略。
据此,您需要从context.Set<TitleInformation>()
开始查询。但为了产生所需的过滤,您需要从 TitleInformation
到 Book
的反向导航属性,目前您的模型中缺少该属性:
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));
或者,如果TitleInformation
和Book
之间的关系是一对多(以上是一对一):
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));
【讨论】:
以上是关于在实体框架核心中的 SelectMany + Select 之后“包含”不起作用的主要内容,如果未能解决你的问题,请参考以下文章