2012-04-22 63 views
2

我有一个LINQ问题,我试图解决,我有一些用户可以成为多个组的一部分,现在我能够返回哪些用户属于一个组,如下所示:LINQ查询常见关联

List<Student> students = new List<Student>(); 
    public List<Student> ReturnStudentByGroupName(string groupName) 
    { 
     List<Student> student = (from g in students 
           where 
            (from t in g.StudentGroup where t.GroupName == groupName select t).Count() > 0 
           select g).ToList(); 
     return student; 
    } 

我现在的问题是我需要找到多个组的普通用户吗?例如,谁是A组和B组的普通成员。我不在寻找这两个组的用户列表,它应该只返回用户如果他们属于这两个组。

有谁知道如何做到这一点使用两个字符串作为输入,即字符串firstgroupName,字符串secondgroupName。然后返回普通学生?

回答

1

嗯,你说你只想要回属于两个组A和B的用户列表,所以自然你只需要用两个条件而不是一个修改where语句。

List<Student> students = new List<Student>(); 
    public List<Student> GetIntersectingStudents(string groupOne, string groupTwo) 
    { 
     var student = from s in students 
         let grps = s.StudentGroup.ConvertAll(gn => gn.GroupName) 
         where grps.Contains(groupOne) && grps.Contains(groupTwo) 
         select s; 
     return student.ToList(); 
    } 
    public List<Student> GetIntersectingStudents(params string[] groups) 
    { 
     var student = from s in students 
         let grps = s.StudentGroup.ConvertAll(gn => gn.GroupName) 
         where !groups.Except(grps).Any() 
         select s; 
     return student.ToList(); 
    } 

这里有你几个方法,其中之一的方法有两个参数(你问什么了),另一个是需要组列表(如果你需要从三个获得,而不是两个等)

编辑:

我以为我会抛出这个额外的方法,在那里也只是为了好玩。它编制了所有小组及其成员的列表。

public static Dictionary<string, List<Student>> GetStudentGroups() 
    { 
     var temp = from s in students 
        let grps = s.StudentGroup.ConvertAll(gn => gn.GroupName) 
        from grp in grps 
        group s by grp 
        into g 
        select g; 
     return temp.ToDictionary(grping => grping.Key, studnt => studnt.ToList()); 
    } 
+0

认真做到了吗? – 2012-04-22 06:45:17

+0

@JungleBoogie:是的,特别是现在我刚修好了。 – caesay 2012-04-22 06:48:08

+0

哈哈是啊我注意到了字符串也好,只是要试一试,并提前接受我的道歉。 – 2012-04-22 06:50:30

2
IEnumerable<Student> StudentsOfGroup(Group g) 
{ 
    return students.Where(s => s.StudentGroup.Contains(g)); 
} 

IEnumerable<Student> CommonStudents(IEnumerable<Group> groups) 
{ 
    return groups 
     .Select(StudentsOfGroup) 
     .Aggregate((acc, g) => acc.Intersect(g)); 
} 

或根据不同群组的数量以下可能会更快:

IEnumberable<Student> CommonStudents(IEnumerable<Group> groups) 
{ 
    var groupSet = new HashSet<Group>(groups); 
    return students.Where(s => groupSet.IsSubsetOf(s.StudentGroup)); 
} 
+0

那么你如何从GET方法中查询呢?如果你注意到我的“string groupName”,我可以使用GET方法来查询并返回结果。 – 2012-04-22 06:23:40

+0

那么,你可以很容易地重写代码来接受'string [] groups'作为输入。 – Grozz 2012-04-22 06:39:39

+2

既然你有一个组类型,你应该使用它。如果组只包含名称(这就是您包含在片段中的所有内容),那么您可以轻松地将字符串列表转换为组对象列表。但在这种情况下,您还应该对第I组猜测实施Equals方法。或者只是重新修改代码以使用字符串... – 2012-04-22 06:43:16

2
IEnumberable<Student> GroupIntersection(IEnumerable<Group> groups) 
{ 
    return students 
     .Where(s => groups.All(g => s.StudentGroup.Contains(g))); 
}