消息在收件箱内显示多次

时间:2011-04-26 11:13:37

标签: c# list merge duplicates duplicate-removal

我的PM系统更像是Google Mail风格。我的意思是消息被分组到对话中。如果用户收到消息,则会显示在收件箱中。此外,此用户会向某人发送消息,然后又会回复,然后此消息也会显示在他们的收件箱中。

在两个查询中都会检索某些消息,这些消息最终会被分组到一个列表中。我试图通过做Jon Skeet在removing duplicates from a list C#中所做的事来删除重复项,但仍然,我一直在重复。这是我的代码:

更新:

public class Message : IEquatable<Message>
{
    public int Id { get; set; }
    [MaxLength(150)]
    public string Subject { get; set; }
    [MaxLength(3000)]
    public string Content { get; set; }
    public DateTime DateSent { get; set; }
    public DateTime? LastViewed { get; set; }
    public bool IsRead { get; set; }
    public bool DisplayInInbox { get; set; }
    public virtual User SentBy { get; set; }
    public virtual User ReceivedBy { get; set; }
    public int? ParentId { get; set; }

    public override bool Equals(object other)
    {
        return Equals(other as Message);
    }

    public bool Equals(Message other)
    {
        if (object.ReferenceEquals(other, null))
        {
            return false;
        }
        if (object.ReferenceEquals(other, this))
        {
            return true;
        }
        return Id == other.Id;
    }

    public override int GetHashCode()
    {
        return this.Id;
    }
}

//在MessagingService中         公共IList GetThreads(用户用户)         {             //获取所有未回复的邮件。             var tmp = _repository.GetMany(c =&gt; c.DisplayInInbox.Equals(true)&amp;&amp; c.ParentId.Equals(null));             var threads =(来自tmp中的c)                           其中GetReplies(user,c.Id).Count()&gt; 0                           选择c).ToList();             var threadsByUser = user.ReceivedMessages.Where(m =&gt; m.DisplayInInbox.Equals(true)&amp;&amp; m.ParentId.Equals(null))。ToList();             threads.AddRange(threadsByUser);             threads.Distinct()ToList();             返回线程;         }

我在这里做错了吗?

3 个答案:

答案 0 :(得分:2)

在两个DTO中你都实现了GatHashcode。在测试相等性时,你不应该使用它们吗?

return Id == other.Id && Subject == other.Subject && SentBy.Nickname == other.SentBy.Nickname &&
           DateSent == other.DateSent;

return Id == other.Id && Subject == other.Subject && Sender == other.Sender;

成为

return GetHashCode() == other.GetHashCode()

编辑:

我也有点傻...不要覆盖/重载equals方法。它是使用GetHashcode确定相等性的equals方法。你已经重载了equals来捕获DTO,默认情况下它会比较两个对象上的GetHashcode的结果。您的重载版本不会比较哈希码,使其变得多余,实际上它看起来像是一个正确的实现。

编辑2(响应帖子中的代码更改):  这很难分辨,因为帖子底部的代码部分没有格式化,但是倒数第二行:

threads.Distinct().ToList();
return threads;

这没有任何作用。合并两者:

return threads.Distinct().ToList();

答案 1 :(得分:2)

如果没有向我们提供任何未被删除的重复消息的示例,我将猜测您在等式检查代码中使用'DateTime'可能是罪魁祸首。这是非常常见的,并且很容易编写类似“ SentDate = DateTime.Now; ”的内容,并且稍后会让系统混淆系统。这只是猜测。

与此同时,我建议你的相等和哈希码功能是进入矫枉过正的领域。现在我假设Message和MessageThread类的'ID'应该是唯一的,在这种情况下你可以真正简化你的逻辑,更容易找到问题的根源,就像这样; < / p>

public override bool Equals(object other)
{
    return Equals(other as Message);
}

public bool Equals(Message other)
{
  if (other == null) { return false; }
  return this.Id == other.Id;
}

public override int GetHashCode()
{
  // If the ID is unique, then it satisfied the purpose of 'GetHashCode'
  return this.Id;
}

显然,您也希望为其他课程执行此操作。这里的好处是移动部件较少,因此出错的机会较少。此外,您无需使用消息正文,发件人等来确定消息的唯一性。

答案 2 :(得分:0)

这可以吗?

return Id == other.Id && Subject == other.Subject && SentBy.Nickname == other.SentBy.Nickname &&
               DateSent == other.DateSent;

我更愿意接受如果id等于,邮件消息是相同的:

return Id == other.Id;