2012-07-17 2 views
0

У меня есть этот запрос:Linq в SQL - запрос, чтобы получить количество(), даже если 0

(from a in SickDays 
    join b in Class.Where(p => p.ID == myId) on a.Class_ID equals b.ID 
    join c in Student on a.Student_ID equals c.ID 
    group a by new { c.Name, c.Order } into ac 
    select new { Count = ac.Count(), Name = ac.Key.Name, Order = ac.Key.Order } 
).OrderBy(f => f.Order) 

Это возвращает:

Count | Name | Order 
    3 | Dave |  a 
    2 | John |  b 
    7 | Sally|  c 

Однако я хотел бы, чтобы вернуть это:

Count | Name | Order 
    3 | Dave |  a 
    2 | John |  b 
    7 | Sally|  c 
    0 | Mark |  d 
    0 | Betty|  e 

UPDATE: Это то, что студенты, классы и SickDays смотрят например, используя пример @sixlettervariables:

var Students = new List<Student>() 
{ 
    new Student { Id = 1, Name = "Al", Order = 'a' }, 
    new Student { Id = 2, Name = "Betty", Order = 'b' }, 
    new Student { Id = 3, Name = "Charles", Order = 'c' }, 
}; 

var Classes = new List<Class>() 
{ 
    new Class { Id = 1, Title = "A100" }, 
    new Class { Id = 2, Title = "A200" }, 
}; 

var SickDays = new List<SickDay>() 
{ 
    new SickDay { Id = 1, StudentId = 1, ClassId = 1 }, 
    new SickDay { Id = 2, StudentId = 1, ClassId = 1 }, 
    new SickDay { Id = 3, StudentId = 1, ClassId = 2 }, 
    new SickDay { Id = 4, StudentId = 1, ClassId = 2 }, 
    new SickDay { Id = 5, StudentId = 2, ClassId = 1 }, 
}; 

ОК, выше, это правильно, поэтому извините за путаницу!

+0

Подождите! Я перепутал себя с «Update». В качестве примера я использовал учеников, классы и SickDays, но мое приложение использует разные объекты - голые со мной несколько минут, в то время как я разбираюсь в том, как выглядят ученики, классы и SickDays. – Dean

+0

Хорошо, теперь это правильно ... снова Мне очень жаль – Dean

ответ

4

Это известно как Left Outer Join. В этом случае каждый Студент требуется, даже если у них нет Sick Days. Итак, мы начнем со студентов, проведем левое внешнее соединение с больными днями, а затем вернем счет классов, которые соответствуют указанному вами идентификатору:

var query = 
    from s in Students 
    join d in SickDays on s.ID equals d.Student_ID into gj 
    from sd in gj.DefaultIfEmpty() 
    group sd by new { s.Name, s.Order } into gg 
    select 
     new 
     { 
      Name = gg.Key.Name, 
      Order = gg.Key.Order, 
      Count = gg.Count(x => x != null && x.Class_ID == myId) 
     }; 
+0

[Это работает, если я понял, что подсчитано.] (Http://ideone.com/p12ts) – user7116

+0

Просто, чтобы вы знали, @sixlettervariables, я все еще тестирую ваше решение. – Dean

+0

Ты чемпион, он работает! Даже когда меня смутило мой собственный вопрос, вы поняли это :-) Большое спасибо! – Dean

0

Значит, вы хотите, чтобы все студенты, даже если они не в классе? Тогда вам нужно левое соединение, я верю. с Linq это достигается с помощью DefaultIfEmpty()

Попробуйте?

(from a in SickDays 
    join b in Class.Where(p => p.ID == myId) on a.Class_ID equals b.ID 
    join c in Student on a.Student_ID equals c.ID 
     into s 
    from students in s.DefaultIfEmpty() 
    group a by new { students.Name, students.Order } into ac 
    select new { Count = ac.Count(), Name = ac.Key.Name, Order = ac.Key.Order } 
).OrderBy(f => f.Order) 

Я надеюсь, что это поможет вам в правильном направлении.

+1

Это не студент, которого нет, а больной день. – user7116

Смежные вопросы