【问题标题】:Complex LINQ query - multiple table relationships复杂的 LINQ 查询 - 多表关系
【发布时间】:2019-11-08 11:17:59
【问题描述】:

我有一个书籍数据库,其中包含作者的 ICollection。我想使用 LINQ 根据 AuthorId 返回作者对象。

Book db

int BookId
string Name { get; set; }
public ICollection<Author> Authors { get; set; }

Author db
int AuthorId
string Name
ICollection<Quote> Quotes { get; set; }
ICollection<Penname> Pennames { get; set; } - Edit: Added for clarity

我试过了:

var test = _context.Book.Include(x => x.Authors).Include("Authors.Quotes")
                    .Select(y => y.Authors)

这给了我:

EntityQueryable<ICollection<Authors>>
[0] {HashSet<Author>} [0]{Author} [1]{Author} [3]{Author} 
[1] {HashSet<Author>} [0]{Author} [1]{Author} 
[2] {HashSet<Author>} [0]{Author} [1]{Author} 

我只是不知道如何迭代作者列表中的作者。类似于以下内容:

var id = 2

var test = _context.Book.Include(x => x.Authors).Include("Authors.Quotes")
                    .Select(y => y.Authors.Select(x => x.Author).Where(x => x.AuthorId == id))

如果我进行重大更新,我可能会使用弹性...

更新@Marko Papic:

谢谢。奇怪的是,如果我使用下面的内容来获取作者的书籍列表,我会得到我期望的引号和笔名列表

var test = _context.Book.Include(x => x.Authors)
                   .ThenInclude(x => x.Quotes)
                   .Include(x => x.Authors)
                   .ThenInclude(x => x.Pennames)

但是,如果我使用 SelectMany,那么引号和笔名最终为 null

var test = _context.Book.Include(x => x.Authors)
                   .ThenInclude(x => x.Quotes)
                   .Include(x => x.Authors)
                   .ThenInclude(x => x.Pennames)
                   .SelectMany(x => x.Authors).Where(x => x.AuthorId == id);

Author myauthor
int AuthorId = 2
string Name = "Bob"
ICollection<Quote> Quotes = null
ICollection<Penname> Pennames = null

【问题讨论】:

  • 你用的是什么版本的EF?
  • 我运行了 dotnet ef --version 并获得了 Entity Framework Core .NET 命令行工具 2.2.4-servicing-10062。这是 ASP.NET Core 2.2
  • 如果您想返回带有特定AuthorIdAuthor 对象,为什么还要使用Books?只需使用_context.Authors.First(a =&gt; a.AuthorId == AuthorId)
  • 如果您要过滤附加到BookAuthors 集合,则不能这样做。例如,请参阅this question
  • 谢谢,我会调查一下

标签: asp.net linq entity-framework-core


【解决方案1】:

你可以使用SelectMany:

var test = _context.Book.Include(x => x.Authors).ThenInclude(x => x.Quotes)
                    .SelectMany(x => x.Authors).Where(x => x.AuthorId == id);

【讨论】:

    【解决方案2】:

    我认为包含被忽略,因为查询的结果类型与您开始时使用的数据库集的类型不同,来自documentation

    如果您更改查询,使其不再返回 查询开始的实体类型,那么包含运算符是 忽略。

    我假设BooksAuthors 之间的关系是多对多的,如果是这种情况,那么我会这样做:

    var query=_context.Authors.Include(a=>a.Books)
                              .Include(a=>a.Quotes)
                              .Include(a=>a.Pennames)
                              .Where(a=> a.AuthorId == id);
    

    【讨论】:

    • Authors 似乎没有 Books 集合?
    • 好吧,我认为他忽略了这一点,OP 也没有显示 AuthorsPennames 并且他在查询中使用它。这应该只是模型的一部分
    • 我很困惑 - 我在上面的 db 模型中添加了笔名以使其更清晰(它与引用相同)。 Books 包含一组作者,其中包含一组引号和笔名。
    • 你知道 Authors 和 Books 的关系是多对多吗?如果是这种情况,您的模型中如何表示?通过联结表还是直接在两个实体之间?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-15
    • 1970-01-01
    • 2020-10-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多