我有一个类似下面的架构(这是一个简化的示例,所以请忽略明显的架构问题):
table Books
{
string bookId
}
table students_books
{
string studentname
string bookId
}
目的是找出阅读量少于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
我在Contains()
上收到了编译错误。查询有什么问题?
无法从使用中推断出方法'System.Linq.Enumerable.Contains< TSource>(System.Collections.Generic.IEnumerable< TSource>,TSource)'的类型参数。尝试明确指定类型参数。
答案 0 :(得分: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;
但我会以更积极的方式表达它 - 实际上是用两个单独的陈述来使它更清晰:
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));
编辑:或者,根据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;
答案 1 :(得分:3)
您在嵌套查询中选择匿名类型,将其替换为select GroupedPerStudent.Key
:
...
where GroupedPerStudent.Count() >= 500
select GroupedPerStudent.Key).Contains(book.bookid)
虽然我会重写整个查询:
var popularBooks = students_books
.GroupBy(b => b.bookId)
.Where(g => g.Count() >= 500)
.Join(Books, students_book => students_book.Key, b => b.bookId,
(students_books, book) => book);