简体   繁体   English

为什么此Linq查询不能带回不同的(唯一的)结果?

[英]Why doesn't this Linq query bring back distinct (unique) results?

I have the following query: 我有以下查询:

 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();

And I want it to bring back a list of unique meetings. 我希望它带回独特的会议清单。 For some reason it brings back an entry for every participant, even though the data is identical: 由于某种原因,即使数据相同,也会为每个参与者返回一个条目:

在此处输入图片说明

Am I missing a grouping somewhere? 我是否在某个地方缺少分组?

EDIT 编辑

The meeting class is currently very basic: 会议课程目前非常基础:

 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; }
}

You can use the way that juharr advise you, or you can implement comparer as separate class that implements IEqualityComparer interface and pass this comparer to distinct. 您可以使用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 ();
    }
}

I believe the reason you get an entry for every participant is that you perform two joins. 我相信您为每个参与者获得一个条目的原因是您执行了两次联接。 You need to do a groupjoin. 您需要进行groupjoin。

 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();

我认为您只需要删除代码的第三行(join ...)。

Is this Linq to Entities? 这是实体的Linq吗? Regardless, I would remove the Distinct and add a group by. 无论如何,我将删除Distinct并添加一个group by。

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();

gabba explained why your code is failing. gabba解释了为什么您的代码失败。 Here's a way you can re-work your query to not even need a Distinct() and make it a little cleaner looking, using a group join: 这是一种使用组联接可以重新处理查询,甚至不需要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()
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM