有没有更快的方法来使用嵌套的linq查询?

时间:2015-11-16 07:32:51

标签: linq linqpad

我正在尝试使用嵌套的linq查询查询表。我的查询工作但速度太慢。我排了差不多400k。这个查询工作10秒,1000行。对于400k,我认为它大约需要2个小时。

我有这样的行

StudentNumber - DepartmentID
n100 - 1
n100 - 1
n105 - 1    
n105 - 2
n107 - 1

我希望学生有不同的部门ID。我的结果看起来像这样。

StudentID - List
n105 - 1 2

我的查询提供了它。但慢慢来。

var sorgu = (from yok in YOKAktarim
    group yok by yok.StudentID into g
    select new {
        g.Key,
        liste=(from birim in YOKAktarim where birim.StudentID == g.Key select new { birim.DepartmentID }).ToList().GroupBy (x => x.DepartmentID).Count()>1 ? (from birim in YOKAktarim where birim.StudentID == g.Key select new { birim.DepartmentID }).GroupBy(x => x.DepartmentID).Select(x => x.Key).ToList() : null,
    }).Take(1000).ToList();


Console.WriteLine(sorgu.Where (s => s.liste != null).OrderBy (s => s.Key));

我用linqpad C#statement写了这个查询。

3 个答案:

答案 0 :(得分:2)

对于400K记录,您应该能够将学生ID和部门ID返回到内存列表中。

 var list1 = (from r in YOKAktarim  
            group r by new { r.StudentID, r.DepartmentID} into g  
            select g.Key
           ).ToList();

获得此列表后,您应该能够按StudentID进行分组,并选择那些拥有多条记录的学生。

  var list2 = (from r in list1 group r by r.StudentID into g 
               where g.Count() > 1 
               select new 
                  { 
                      StudentID = g.Key, 
                      Departments = g.Select(a => a.DepartmentID).ToList()
                  }  
               ).ToList();

这应该更快,因为它只能访问sql数据库一次,而不是数十万次。

答案 1 :(得分:1)

您正在迭代源集合(YOKAktarim)三次,这使您的查询* O(n ^ 3)`查询。这会很慢。

不是回到源集合来获取组的内容,而是可以简单地遍历g

var sorgu = (from yok in YOKAktarim
    group yok by yok.StudentID into g
    select new {
        g.Key,
        liste = from birim in g select new { birim.DepartmentID }).ToList().GroupBy (x => x.DepartmentID).Count()>1 ? (from birim in g select new { birim.DepartmentID }).GroupBy(x => x.DepartmentID).Select(x => x.Key).ToList() : null,
    }).Take(1000).ToList();

然而,这仍然不是最佳的,因为你正在进行大量的冗余子分组。您的查询几乎相当于:

from yok in YOKAktarim
group yok by yok.StudentID into g
let departments = g.Select(g => g.DepartmentID).Distinct().ToList()
where departments.Count() > 1
select new {
    g.Key,
    liste = departments
}).Take(1000).ToList();

答案 2 :(得分:-3)

我无法说出该怪物的正确性,但只是移除除最外面的所有<ListView Name="listView1" ItemsSource="{Binding Cars}"> <i:Interaction.Triggers> <i:EventTrigger EventName="LeftDoubleClick"> <i:InvokeCommandAction Command="{Binding ItemSelectCommand}" CommandParameter="{Binding ElementName=listView1,Path=SelectedItem}" /> </i:EventTrigger> </i:Interaction.Triggers> </ListView> 个电话,这样可以解决您的问题。