0

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

在两个查询中都检索到一些消息,这些消息最终被分组到一个列表中。我试图通过执行 Jon Skeet从 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 内部 public IList GetThreads(User user) { //获取所有未回复的消息。var tmp = _repository.GetMany(c => c.DisplayInInbox.Equals(true) && c.ParentId.Equals(null)); var threads = (from c in tmp where GetReplies(user, c.Id).Count() > 0 select c).ToList(); var threadsByUser = user.ReceivedMessages.Where(m => m.DisplayInInbox.Equals(true) && m.ParentId.Equals(null)).ToList(); 线程.AddRange(threadsByUser); 线程.Distinct().ToList(); 返回线程;}

我在这里做错了吗?

4

3 回答 3

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();
于 2011-04-26T13:28:18.423 回答
2

在不向我们提供任何未删除的重复消息的示例的情况下,我猜测您在相等检查代码中使用“日期时间”可能是罪魁祸首。这很常见,也很容易写出类似 ' SentDate = DateTime.Now; ' 并让它在以后混淆系统。这只是一个猜测。

同时,我建议您的相等和哈希码函数进入过大的领域。现在我将假设 Message 和 MessageThread 类的“ID”应该是唯一的,在这种情况下,您可以真正简化您的逻辑,并且更容易找到问题的根源,就像这样;

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

显然,您也希望为您的其他课程这样做。这样做的好处是活动部件更少,因此出错的机会更少。此外,您不需要邮件正文、发件人等来确定邮件的唯一性。

于 2011-04-26T13:47:45.487 回答
0

这个可以吗?

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

我更喜欢如果 id 等于,邮件消息相同的方法:

return Id == other.Id;
于 2011-04-26T13:15:17.010 回答