2012-04-22 65 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))); 
}