更高效的LINQ连接

更高效的LINQ连接,linq,join,Linq,Join,我试图用一对五的关系连接两个表,但我只希望“一”列数据出现在一行中,其他所有行中的数据都应该为null(不管是哪一行)。因此: 示例:您希望获得所有名为“Joe”的学生,使用TeacherID加入教师,但限制返回的结果,以便不在每一行返回教师数据。究其原因,是因为教师人数多;我需要退货,但不是每排都要 因此,一些示例输出应该如下所示: ------------------------------------------------ StudentFName | StudentLName | Te

我试图用一对五的关系连接两个表,但我只希望“一”列数据出现在一行中,其他所有行中的数据都应该为null(不管是哪一行)。因此:

示例:您希望获得所有名为“Joe”的学生,使用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
.
.
.
.
因此,在Michaels和Washington的例子中,TeacherBiograph(以及所有其他教师列)是空的,因为数据已经在Smith行中返回

我该怎么做


-J

我认为唯一有效的方法是将
学生
s和
教师
s与
教师ID
作为一个键连接起来,然后您可以只为一行输出一次该键,为同一个键输出另一行,如下所示:

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);
     }
}

我会分两步完成这项工作,而不是让代码复杂化,试图在一步中完成。首先,检索您关心的学生信息。一旦有了这些信息,您就可以执行另一个查询来获取教师信息,给出了教师ID的不同列表

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};

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

对不起,这比在DB的结果中多次发送完全相同的长传记列更有效。除非我遗漏了什么,否则这只是在进行连接,并且仍然从DB发送大量重复的教师。我没有试图有效地打印结果,我只是试图有效地从数据库中获取结果。@user1346563,这不是从数据库中获取大量重复的教师,它将以教师->学生列表的形式出现,即。e、 :每个教师都有一个学生列表,如果您使用LINQ to sql,您的查询将在数据库端执行,您将不会担心效率。如果您想进行查询,以获取问题中发布的表单中的数据列表,那么您可以手动编写列表,迭代每个学生,仅为第一个学生获取其对应的教师,其余的添加
null
。这将使您的查询完全无效。不管我们心目中的关系对象结构(教师->学生)如何,在数据库和查询中,数据库将向客户端发送一堆“扁平”行,而不是指向学生对象的教师对象(至少我认为会)。因此,当它在DB端将它们展平以发送回客户机时,它是否会复制TeacherID相同的每一行中的教师列?当我在调试器中查看查询结果时,看起来数据是重复的,但这可能是DB驱动程序“智能”的客户端。@user1346563,现在有一种方法可以使用一个查询来实现这一点,
join
是唯一的方法,也是最有效的方法。无论如何,如果你想这样做,你必须像我说的那样手动进行,对于每一行,你必须检查重复的分组教师,并用null替换它们,这个检查将降低你的查询效率。是的,我想过这样做,但这似乎是一个常见的问题(每个一对多的联接在某种程度上都会受到这个问题的影响)必须有一个简单、单一的查询解决方案?
var allData = from s in students
    join t in teachers on
    t.teacherID equals s.TeacherID
    select new { StudentName = s.Name, TeacherBio = t.TeacherBiography};