2013-02-28 188 views
0

我有一個的DbContext這四個許多一對多相關實體:複雜的投影

Classes <-> Students 
Classes <-> Assignments 
Classes <-> Contents 
Classes <-> Announcements 

現在我需要一個LINQ代碼(或者更好!)這將給我們最後3個作業,最後3個內容,最後3個公告每個類的學生與StudentId = X是在那些類。

另一方面,學生登錄網站,我們想向他/她展示他/她最近的作業,內容,他/她在其中學習的每個課程的公告。

這段代碼不正確,但可能會幫助你理解我的需要。此代碼也需要多次運行(50ms不是很多?):

編輯:代碼幾乎是正確的,所以感動回答,看看接受的答案。任何其他(更好,更快)的解決方案表示讚賞

在此先感謝。

+1

與我的代碼不同的是,你只有一個'SelectMany'類。我的代碼有更多的'SelectMany'。我認爲你的代碼更好。那麼你現在還有問題嗎?否則,你可以把你的代碼放在你自己問題的答案中,並將其標記爲已接受。 – 2013-03-01 08:06:21

回答

0

基於@格特·阿諾德建議我改變一點點我的代碼:

  • 開始查詢與學生
  • 通過改變所選屬性縮小結果
db.Students.Where(st => st.StudentId.Equals(CurrentUser)).SelectMany(S => S.Classes, (S, C) => new 
{ 
    Name = C.Name, 
    Assignments = C.Assignments.Select(AS => new { AS.Id, AS.Name }).OrderByDescending(As => As.Id).Take(3), 
    Contents = C.Contents.Select(Co => new { Co.Id, Co.Title }).OrderByDescending(Co => Co.Id).Take(3), 
    Announcements = C.Announcements.Select(An => new { An.Id, An.Title }).OrderByDescending(An => An.Id).Take(3) 
}); 
0

你最好開始與學生查詢:

from s in db.Students 
where s.StudentId == CurrentUser 
from c in s.Classes 
from as in c.Assignments.OrderByDescending(As => As.Id).Take(3) 
from co in c.Contents.OrderByDescending(Co => Co.Id).Take(3) 
from an in c.Announcements.OrderByDescending(An => An.Id).Take(3) 
select new { <selected properties> } 

最後一部分(選擇屬性)是非常重要的。通過只選擇屬性的一個子集,可以從數據庫中縮小結果集。如果沒有這一點,由於(SQL)查詢中的大量連接,您將創建一個非常寬且很長的結果集。

+0

謝謝你的傢伙你的好建議,我等待也許別人有更好的答案(更快)。另一個問題:我的新代碼工作,但消耗時間(我的PC作爲EntityFrameworkProfiler 50ms),是否有可能存在問題,如果1000學生同時請求這個頁面?此外EntityFrameworkProfiler警告我_避免太多joins_。任何更快的方式? [鏈接](http://hibernatingrhinos.com/products/EFProf/learn/alert/TooManyJoins)。 – 2013-03-01 12:56:04