2011-03-29 61 views
1

我有一個像下面的模式(這是一個簡單的例子,所以請無視明顯的架構問題):LINQ集團通過而不是

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)' 不能從使用推斷。嘗試明確指定類型參數。

回答

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); 
+0

感謝您的建議。你可以讓我知道這兩個查詢之間的區別是什麼? – user682732 2011-03-29 20:01:18

+0

@user,區別在於在你的查詢中你嵌套了子查詢,這比我的查詢可以一行一行讀取更難讀。我的第二個查詢實際上與Jon的答案中的最後一個查詢相同,但在使用Linq語法編寫查詢時使用'Enumerable'方法編寫。我會說,如果你喜歡Linq語法,你應該使用第二或第三個Jon的查詢,否則使用我的第二個查詢。 – Snowbear 2011-03-29 20:04:55

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; 
+0

呃,不知道你可以繼續這樣查詢。儘管我個人不喜歡這種語法。 – Snowbear 2011-03-29 19:54:10

+0

@jonskeet,玩了一會兒編譯器,看起來你的'group .. by grouped'在'分組'之前缺少了另一個表達式和一個'into',但是除此之外,你是在點對點的。 – devgeezer 2013-02-15 11:39:51

+0

@devgeezer:現在再看一下 - 我認爲它在那裏。 – 2013-02-15 11:51:32