代码之家  ›  专栏  ›  技术社区  ›  Joe Enos

过滤实体框架查询中的“Includes”表

  •  17
  • Joe Enos  · 技术社区  · 14 年前

    我需要查询一个表并包含一对多关系的“many”表的集合。我正在尝试将该集合作为查询的一部分进行过滤-我对实体框架非常陌生,但我很难弄清楚它。

    没有过滤器,很容易:

    var q = from a in db.Authors.Include("Books")
            where a.BirthYear > 1900
            select a;
    

    var fictionBooks = a.Books.Where(b => b.IsFiction);
    

    但问题是原始查询已经运行,并且包含了那些结果,这是不必要的数据库处理。

    var q = from a in db.Authors where a.BirthYear > 1900 select a;
    foreach (var a in q)
    {
        var books = from b in db.Books 
                    where ((b.Author.Id == a.Id) && (b.IsFiction))
                    select b;
    }
    

    我可以倒回去,比如:

    var allBooks = from b in db.Books.Include("Author")
                   where b.IsFiction
                   select b;
    

    但是我又回到了最初的问题,除了现在是作者方面,而不是书本方面。

    select * from author a
    left join book b on a.id = b.author_id and b.is_fiction = 1
    where a.birth_year > 1900
    

    有什么建议吗?

    1 回复  |  直到 14 年前
        1
  •  16
  •   Timwi    14 年前

    前进的道路:

    var q = from a in db.Authors.Include("Books")
            where a.BirthYear > 1900
            select new {
                Author = a,
                FictionBooks = a.Books.Where(b => b.IsFiction)
            };
    

    另一种方式,来自问题底部的SQL:

    var q = from a in db.Authors
            from b in db.Books.Include("Author")
            where a.BirthYear > 1900 && b.IsFiction && a.Id == b.Author.Id
            select new { Author = a, Book = b };
    

    这两者之间的主要区别是,第一个基本上会给你一个作者的集合,加上每个作者的小说书籍列表(可能是空的);而第二个将给您一个作者/书籍对的集合(因此它不会返回任何没有小说书籍的作者)。