LINQ Group By和NOT in

use*_*732 1 linq

我有一个类似下面的架构(这是一个简化的示例,所以请忽略明显的架构问题):

table Books
{
    string bookId
}

table students_books
{
    string studentname
    string bookId
}
Run Code Online (Sandbox Code Playgroud)

目的是找出阅读量少于500次的书籍.不幸的是,我无法在书桌上保留这一数字.

我正在编写这样的查询:

from book in Books
    where !(from student in students_books
        group student by student.bookId into GroupedPerStudent
        where GroupedPerStudent.Count() >= 500 
        select new { bookname = GroupedPerStudent.Key }).Contains(book.bookid)
    select book 
Run Code Online (Sandbox Code Playgroud)

我收到了编译错误Contains().查询有什么问题?

无法从用法推断出方法'System.Linq.Enumerable.Contains <TSource>(System.Collections.Generic.IEnumerable <TSource>,TSource)'的类型参数.尝试显式指定类型参数.

Jon*_*eet 5

您的嵌套查询正在选择匿名类型 - 您应该选择书籍ID:

from book in Books
  where !(from student in students_books
          group student by student.bookId into GroupedPerStudent
          where GroupedPerStudent.Count() >= 500 
          select GroupedPerStudent.Key).Contains(book.bookid)
select book;
Run Code Online (Sandbox Code Playgroud)

但我会以更积极的方式表达它 - 实际上是用两个单独的陈述来使它更清晰:

var rarelyRead = from student in student_books
                 group student by student.bookId into grouped
                 where grouped.Count() < 5000
                 select grouped.Key;

var query = Books.Where(book => rarelyRead.Contains(book.book_id));
Run Code Online (Sandbox Code Playgroud)

编辑:或者,根据Snowbear的建议,使用连接,我们将使用查询延续的乐趣:

var query = from student in student_books
            group student by student.bookId into grouped
            where grouped.Count() < 5000
            select grouped.Key into rarelyRead
            join book in Books on rarelyRead equals book.book_id
            select book;
Run Code Online (Sandbox Code Playgroud)