[英]How to do Linq Many to Many join with or without navigation properties
這個問題在stackoverflow上已經問過好幾次了,我已經讀了至少六個,但是我無法理解簡單的多對多linq join查詢。 這是我的數據庫EDMX
我只是試圖用學生列表以及每個學生的科目填充WPF數據網格。
現在我知道我們可以簡單地使用導航屬性,而不是進行聯接,但是我一直無法獲得正確的結果
所以(C#/ VB.net)查詢就像
var listOfStudents= // get a list with all students , along with each student's subjects
謝謝您的任何幫助,它的查詢非常簡單,但我有點卡住了
var listOfStudents = db.Student.Select(x => new { Id = x.Id, Name = x.StudentName, Subjects = x.StudentsSubjects.Select(y => y.Subject) });
如果刪除Id
從表中的字段StudentsSubject
然后從模型中刪除該表並更新你的模型,EF會自動將這個表有兩種導航性能Subjects
和Students
的Student
和Subject
分別實體。
如果必須保留StudentSubject表架構不變,則可以使用Include()
方法來獲取學生及其科目:
var students = dbContext.Students.Include("StudentsSubject.Subject")
使用“常規”導航屬性,您可以編寫以下內容:
var students = dbContext.Students.Include("Subjects")
有時您需要組裝大圖,然后Include()和延遲加載會影響性能。 這種情況有一個小技巧:
// switch off for performance
DbContext.Configuration.AutodetectChangesEnabled = false;
// load root entities
var roots = dbContext.Parents.Where( root => %root_condition%).ToList();
// load entities one level lower
dbContext.DependentEntities.Where( dependent => dependent.Root%root_condition% && %dependent_condition%).ToList();
// detect changes
dbContext.ChangeTracker.DetectChanges();
// enable changes detection.
DbContext.Configuration.AutodetectChangesEnabled = true;
現在root.Dependents
集合填充了roots
。
這是聯接冗余(包括或聯接)和幾個數據庫請求之間的權衡,同時請求的復雜性也在不斷提高。
使用“包含”可以復制連接節點的數據,因此包含鏈可以產生從數據庫到客戶端的巨大流量。
使用第二種方法,每個級別都需要在Where()中過濾所有更高級別的條件,並且EF使用第N個級別的N-1個聯接生成查詢,但是沒有多余的地方。
據我所知,EF現在可以與Contains()一起正常工作,並且可以使用Contains()
替換父節點的條件:
// load root entities
var roots = dbContext.Parents.Where( root => %root_condition%).ToList();
var rootIds = new List<int>( roots.Select( root => root.Id));
// load entities one level lower
dbContext.DependentEntities.Where( dependent => %dependent_condition% && rootIds.Contains( dependent.RootId)).ToList();
常規的LINQ連接應該可以解決問題。 這是一個簡化的測試用例:
Public Class Student
Public Property Id As String
Public Property StudentName As String
Public Property GPA As String
End Class
Public Class StudentsSubject
Public Property SubjectId As String
Public Property StudentId As String
Public Property Id As String
End Class
Public Class Subject
Public Property Id As String
Public Property SubjectName As String
End Class
Sub Main()
Dim students As New List(Of Student)
students.Add(New Student With {.Id = "1", .GPA = "GPA1", .StudentName = "John"})
students.Add(New Student With {.Id = "2", .GPA = "GPA2", .StudentName = "Peter"})
Dim subjects As New List(Of Subject)
subjects.Add(New Subject With {.Id = "100", .SubjectName = "Maths"})
subjects.Add(New Subject With {.Id = "200", .SubjectName = "Physics"})
Dim studentsSubject As New List(Of StudentsSubject)
studentsSubject.Add(New StudentsSubject With {.Id = "10", .StudentId = "1", .SubjectId = "100"})
studentsSubject.Add(New StudentsSubject With {.Id = "20", .StudentId = "1", .SubjectId = "200"})
studentsSubject.Add(New StudentsSubject With {.Id = "30", .StudentId = "2", .SubjectId = "100"})
Dim listOfStudents = From st In students
Join ss In studentsSubject On ss.StudentId Equals st.Id
Join sb In subjects On ss.SubjectId Equals sb.Id
Select st.StudentName, st.GPA, sb.SubjectName
End Sub
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.