2013-12-18 106 views
0

試圖找出如何執行LINQ to Entities查詢以獲得與字段表有關的多對多關係。EF LINQ to Entites查詢多對多關係

以下是域模型(我正在使用視圖模型,但爲此示例保持簡單)。

Student Domain model 
StudentID (PK) 
ICollection<StudentCourse> StudentCourses 

StudentCourse Domain model 
StudentCourseID (PK) 
StudentID (FK) 
CourseID (FK) 
ForAdult 
ForSeniour 
Description 

Course Domain model 
CourseID (PK) 
ICollection<StudentCourse> StudentCourses 

注:

  • 由於結表(即StudentCourse)含有比兩個外鍵等領域,EF將爲此創造一個實體。

延遲加載

我得到這個工作了延遲加載。導航屬性已用「虛擬」關鍵字聲明。

查詢方式 - 工作!

var student = (from s in context.Students 
       where s.StudentID == id 
       select s).SingleOrDefault<Student>() 

方法方法 - 工作!

Student student = context.Students.Find(id); 

投影

,但我寧願與投影要做到這一點,出於性能考慮,即前往數據庫少。

我真的被困在如何寫LINQ to Entities查詢來返回1學生(1或)許多StudentCourses。

如果你知道我的意思,我不完全理解實體應該如何成形。 舉例來說,我已經試過:

var myvar = from s in context.Students 
      from sc in s.StudentCourses 
      where s.StudentID == id 
      select s 

什麼我需要是返回學生的實體StudentCourses集合然後可以被分配給學生,並傳遞給視圖模型,然後查看。

真的很感謝任何幫助,因爲我花了很多時間來解決這個問題。另外作爲一個便箋,我使用SingleOrDefault()方法將var(IQueryable我認爲)的結果強制轉換爲Student類型。這是鑄造的首選方式嗎?

回答

1

您可以通過使用Include方法來獲取EF以便加載相關實體。

所以使用LINQ例如:

var student = (from s in context.Students 
       where s.StudentID == id 
       select s).Include("StudentCourses").FirstOrDefault(); 

而使用擴展方法:

var student = context.Students.Include("StudentCourses").FirstOrDefault(id); 

時返回將有StudentCourses收集填充了相關實體的Student實例。這應該只調用一個將表連接在一起的SQL查詢。

回答你的問題:我更喜歡在上面大多數時候使用FirstOrDefault。不同之處在於SingleOrDefault預期爲exactly one result,否則引發異常,而如果找不到學生,FirstOrDefault將返回null

此外,由於Student是隱含的,您不需要<Student>類型參數。

+0

這工作,非常感謝。出於性能原因,我會限制列和篩選行,即減少從數據庫返回的結果集,因此需要查詢投影。 –

+0

爲了學習Eager加載的其他人的利益,你也可以做嵌套包含。在上面的例子中,我們還包含一個SubCourse域模式,它是StudentCourses上的一個導航屬性(它可能或可能不會與課程領域模型物理鏈接)。這裏有一段代碼可以帶回一個學生,它是一個或多個StudentCourse(s),它是一個或多個課程,最後它是一個或多個子課程:var student =(從s in context .StudentID == id select s).Include(「StudentCourses.Course」)。Include(「StudentCourses.SubCourse」)。FirstOrDefault();' –