2014-10-17 49 views
0

我有以下查詢:爲什麼Linq查詢不能帶回獨特的結果?

List<Meeting> meetings = 
    (from m in crdb.tl_cr_Meetings 
    join p in crdb.tl_cr_Participants on m.MeetingID equals p.MeetingID 
    where p.TimeOut == null 
    select new Meeting 
     { 
     MeetingID = m.MeetingID, 
     MeetingName = m.MeetingName, 
     HostUserName = m.HostUsername, 
     BlueJeansMeetingID = m.tl_cr_BlueJeansAccount.MeetingID, 
     StartTime = m.StartTime, 
     Participants = (from pa in crdb.tl_cr_Participants 
         where pa.MeetingID == m.MeetingID 
         select pa.tl_cr_BlueJeansAccount.DisplayName).ToList() 
       }).Distinct().ToList(); 

而且我希望它帶回來的唯一的會議列表。出於某種原因,它勾起了每個參與者的進入,即使數據是相同的:我缺少

enter image description here

是一個分組的地方?

編輯

會議類是目前十分簡單:

public class Meeting 
{ 
    public int MeetingID { get; set; } 
    public string MeetingName { get; set; } 
    public string HostUserName { get; set; } 
    public DateTime StartTime { get; set; } 
    public List<string> Participants { get; set; } 
    public string BlueJeansMeetingID { get; set; } 
} 
+3

,你能否告訴了'Meeting'類的代碼?它是否實現了'IEquatable'?你可能想看到這個[問題](http://stackoverflow.com/questions/1365748/distinct-not-working-with-linq-to-objects) – juharr 2014-10-17 17:37:50

回答

2

我相信你得到每個參與者的條目的原因是你執行兩個連接。 你需要做一個羣組加入。

var meetings = crdb.tl_cr_Meetings.GroupJoin(crdb.tl_cr_Participants, 
               k => k.MeetingID, 
               k => k.MeetingID, 
               (o,i) => new Meeting 
               { 
                MeetingID = o.MeetingID, 
                MeetingName = o.MeetingName, 
                HostUserName = o.HostUsername, 
                BlueJeansMeetingID = o.tl_cr_BlueJeansAccount.MeetingID, 
                StartTime = o.StartTime, 
                Participants = i.Select(s => s.DisplayName) 
               }).ToList(); 
+0

這是完美的。我以前沒有遇到過GroupJoin。看了這個http://www.dotnetperls.com/groupjoin,現在明白了上述的工作原理! – Ben 2014-10-17 18:21:49

+0

太棒了,很高興我能幫上忙! – DaEagle 2014-10-17 18:31:17

2

您可以使用juharr勸你的方式,也可以實現比較器作爲單獨的類,它實現的IEqualityComparer接口,並通過該比較器以區分。

public class MeetingComparer : IEqualityComparer<Meeting> 
{ 
    public bool Equals (Meeting x, Meeting y) 
    { 
     return x.smth.Equals (y.smth); 
    } 

    public int GetHashCode (Meeting obj) 
    { 
     return obj.smth.GetHashCode(); 
    } 
} 
1

我想你只需要刪除第三行代碼(join ...)。

+0

這裏唯一的麻煩是,我需要加入來檢查會議只包含p.TimeOut爲空的參與者。 – Ben 2014-10-17 18:11:53

1

這是Linq的實體嗎?無論如何,我會刪除Distinct並添加一個組。

List<Meeting> meetings = 
    (from m in crdb.tl_cr_Meetings 
    join p in crdb.tl_cr_Participants on m.MeetingID equals p.MeetingID 
    where p.TimeOut == null 
    group m by new { m.MeetingID, m.MeetingName, m.HostUsername, MeetingID2 = m.tl_cr_BlueJeansAccount.MeetingID, m.StartTime } into m 
    select new Meeting 
    { 
     MeetingID = m.Key.MeetingID, 
     MeetingName = m.Key.MeetingName, 
     HostUserName = m.Key.HostUsername, 
     BlueJeansMeetingID = m.Key.MeetingID2, 
     StartTime = m.Key.StartTime, 
     Participants = (from pa in crdb.tl_cr_Participants 
         where pa.MeetingID == m.Key.MeetingID 
         select pa.tl_cr_BlueJeansAccount.DisplayName).ToList() 
    }).ToList(); 
+0

組連接可以很好地清理此查詢。 – 2014-10-17 17:57:33

+0

@CoryNelson - 你是什麼意思? – Aducci 2014-10-17 17:58:38

1

gabba解釋了你的代碼失敗的原因。這裏有一個方法,你可以重新工作,您的查詢,甚至不需要Distinct()並使其乾淨了一點看,使用一組連接:

from m in crdb.tl_cr_Meetings 
join p in crdb.tl_cr_Participants on new { m.MeetingID, null } 
        equals new { p.MeetingID, p.TimeOut } into meetingParticipants 
select new Meeting 
{ 
    MeetingID = m.MeetingID, 
    MeetingName = m.MeetingName, 
    HostUserName = m.HostUsername, 
    BlueJeansMeetingID = m.tl_cr_BlueJeansAccount.MeetingID, 
    StartTime = m.StartTime, 
    Participants = meetingParticipants 
         .Select(x => x.tl_cr_BlueJeansAccount.DisplayName) 
         .ToList() 
} 
相關問題