2012-04-20 57 views
0

我想加入兩個表與一個可能的關係,但我只想要「一個」列數據出現在一行中,它應該在所有其他行中爲空(不關心哪個)。所以:更有效的LINQ加入

TEACHER 
--------- 
TeacherID 
TeacherBiography 
. 
. 
. 

STUDENT 
----------- 
TeacherID 
StudentFName 
StudentLName 
. 
. 
. 

例子:你想要得到的所有誰的名字是「喬」的學生,加入使用TeacherID教師,但限制返回的結果,使教師的數據不是每行返回。原因是因爲老師傳記很大;我需要它返回,但不是在每一行。

因此,一些樣本輸出應該是這樣的:

------------------------------------------------ 
StudentFName | StudentLName | TeacherID | TeacherBiography 
------------------------------------------------ 
'Joe'  | 'Smith'  | 1   | 'long biography for teacher 1..' 
'Joe'  | 'Jones'  | 2   | 'long biography for teacher 2..' 
'Joe'  | 'Michaels' | 1   | null 
'Joe'  | 'Rogers'  | 3   | 'long biography for teacher 3..' 
'Joe'  | 'Washington' | 1   | null 
. 
. 
. 
. 

所以在邁克爾和華盛頓的情況下,TeacherBiograph(和所有其他老師列)爲空,因爲數據是在史密斯一行已經返回。

我該怎麼做?

-J

+2

「更高效」比什麼? – Magnus 2012-04-20 13:19:15

+0

對不起,比從DB發送多次完全相同的長傳記列效率更高效。 – user1346563 2012-04-20 13:42:36

回答

0

我認爲唯一有效的方式做,這是加入STUDENT S和TEACHER s的的TeacherID作爲重點,那麼你就可以輸出該鍵只有一個時間只有一個行和其他行對於同一個密鑰輸出null代替,就像這樣:

var StudentsList = students.Join( //Inner join 
    Teachers, 
    s => s.TeacherID, 
    t => t.TeacherID, 
    (teacher, teacherStudetns) => 
     new 
     { 
      Teacher = teacher, 
      HisStudents = teacherStudetns 
     }); 

那麼你只能輸出一次鍵,例如:

foreach(var item in StudentsList) 
{ 
    Console.Writline("Teach Name: {0}, His students:", item.TeacherBiography); 
    foreach(var student in item.HisStudents) 
    { 
     Console.writeLine("---------- {0}", student.StudentName); 
    } 
} 
+0

除非我錯過了一些東西,這只是在做一個JOIN,並且仍然從DB中發回大量重複的教師。我沒有試圖高效地打印結果,我試圖高效地從數據庫中獲取結果。 – user1346563 2012-04-20 14:07:46

+0

@ user1346563,這不是從數據庫中獲取大量的重複教師,它將以* teacher - > student *,i列表的形式出現。 e .:每個教程都有一個學生列表,如果您使用的是LINQ to sql,您的查詢將在數據庫端執行,您不會對效率感到擔憂。如果您想讓查詢以您在問題中發佈的表單的形式獲取數據列表,那麼您可以手動編寫您的列表,讓每個學生只在第一個學生獲取其相應的老師時爲其添加「null」。這會使你的查詢完全沒有效率。 – 2012-04-20 15:19:43

+0

無論關係對象結構(教師 - >學生)如何,我們在我們的頭腦中,在數據庫和查詢中,數據庫都會將一堆「扁平」行發送回客戶端,而不是教師對象指向學生對象(至少我認爲會)。所以當它在數據庫端扁平化併發送回客戶端時,它是否會複製TeacherID相同的每行中的教師列?當我查看調試器中的查詢結果時,看起來數據是重複的,但可能是數據庫驅動程序的「智能」客戶端。 – user1346563 2012-04-20 15:37:43

0

我會在兩個步驟中做到這一點,而不是讓您的代碼複雜化,以嘗試在一個完成。首先,檢索您關心的學生信息。一旦你有了,你可以執行另一個查詢來獲取教師信息,給定不同的TeacherID列表。

var students = //student query 
var teacherIds = students.Select(p => p.TeacherID).Distinct(); 
var teachers = teacherTable.Where(p => p.Contains(teacherIds)); 

然後你可以在內存中加入兩個結果。

var allData = from s in students 
    join t in teachers on 
    t.teacherID equals s.TeacherID 
    select new { StudentName = s.Name, TeacherBio = t.TeacherBiography}; 

這將導致兩個數據庫訪問,但你只會返回你需要的數據項。

+0

是的,我想過這樣做,但似乎是這樣一個普遍的問題(每個一對多連接在某種程度上都受到這個問題的困擾)必須有一個簡單的單一查詢解決方案? – user1346563 2012-04-20 14:12:33