更高效的LINQ JOIN

时间:2012-04-20 13:17:07

标签: linq join

我正在尝试将两个表连接成一个可能的关系,但我只希望“一个”列数据出现在一行中,它应该在所有其他行中都为null(不关心哪些行)。所以:

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

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

示例:您希望所有名字为“Joe”的学生,使用TeacherID加入教师,但限制返回的结果,以便每行不返回教师数据。原因是因为TeacherBiography很大;我需要它返回,但不是每一行。

因此,一些示例输出应如下所示:

------------------------------------------------
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
.
.
.
.

因此,在Michaels和华盛顿的情况下,TeacherBiograph(以及所有其他教师专栏)为空,因为数据已经在史密斯行中返回。

我该怎么做?

-J

2 个答案:

答案 0 :(得分:0)

我认为唯一有效的方法是以STUDENT作为键加入TEACHERTeacherID s,然后只能输出此键一次相同的键输出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);
     }
}

答案 1 :(得分: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};

这将导致两次数据库命中,但您只会返回所需的数据项。