Search code examples
c#linqasp.net-core-6.0

select List where sub-list contains is all item from another list with linq


I have a model with list items:

public class Student{
    public int StudentId { get; set; }
    public int ClassId { get; set; }
}

The table values are similar to the following:

StudentId ClassId
1 8
2 6
1 3
3 8
2 3
3 2
4 8
1 6
3 6
2 2

classId list for filter:

ClassId
8
6

I want to select the list of StudentId where are in all filter classId.

StudentId
1
3

I use this code but not working:

List<int> lstStudentId = Students.GroupBy(o => o.StudentId).Where(o => o.All(m => filterClassId.All(s => s == m.ClassId ))).Select(o => o.Key).ToList();

Solution

  • You write :

    List<int> lstStudentId = Students
        .GroupBy(o => o.StudentId)
        .Where(o => o.All(m => filterClassId.All(s => s == m.ClassId)))
        .Select(o => o.Key).ToList();
    

    The Where check all student's classes are in the filter... but you want the inverse, all filtered classes are in the student.

    Just reverse the condition :

    var lstStudentId = Students
        .GroupBy(o => o.StudentId)
        .Where(g => filterClassId.All(f => g.Any(s => s.ClassId == f)))
        .Select(g => g.Key)
        .ToList();
    

    A alternative, it's to check if the filter less the student's class result in nothing. Then the student has all class in the filter :

    var lstStudentId = Students
        .GroupBy(o => o.StudentId)
        .Where(g => !filterClassId.Except(g.Select(s => s.ClassId)).Any())
        .Select(g => g.Key)
        .ToList();