Сообщение появляется несколько раз в папке «Входящие» - PullRequest
0 голосов
/ 26 апреля 2011

У меня есть система PM, которая больше похожа на стиль Google Mail.Я имею в виду сообщения сгруппированы в разговоры.Если пользователь получает сообщение, оно появляется в папке «Входящие».Кроме того, этот пользователь отправляет сообщение тому, кто, в свою очередь, отвечает обратно, а затем это сообщение также появляется в папке входящих сообщений.

Некоторые сообщения извлекаются в обоих запросах, которые в итоге группируются в один список.Я попытался удалить дубликаты, выполнив то, что сделал Джон Скит в , удалив дубликаты из списка 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 = (из c в tmp, где GetReplies (пользователь, c.Id) .Count ()> 0 select c) .ToList ();var threadsByUser = user.ReceivedMessages.Where (m => m.DisplayInInbox.Equals (true) && m.ParentId.Equals (null)). ToList ();threads.AddRange (threadsByUser);threads.Distinct () ToList ().возврат темы;}

Я что-то здесь не так делаю?

Ответы [ 3 ]

2 голосов
/ 26 апреля 2011

В обоих 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()

EDIT:

Я тоже немного потрудился ... не переопределяйте / не перегружайте метод equals. Это метод equals, который использует GetHashcode для определения равенства. Вы перегружены, равно, чтобы поймать DTO, который по умолчанию сравнил бы результат GetHashcode для обоих объектов. Ваша перегруженная версия не сравнивает хеш-код, что делает его избыточным, когда на самом деле это выглядит как правильная реализация.

РЕДАКТИРОВАТЬ 2 (в ответ на изменения кода в вашем сообщении): Трудно сказать, потому что раздел кода в нижней части вашего поста не отформатирован, а содержит в себе строку с последней до последней строки:

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

Это ничего не делает. Объединить два:

return threads.Distinct().ToList();
2 голосов
/ 26 апреля 2011

Не предоставив нам ни одного примера ваших дубликатов сообщений, которые не удаляются, я собираюсь предположить, что использование вами DateTime в вашем коде проверки равенства является вероятным виновником. Это очень распространено, и легко написать что-то вроде ' SentDate = DateTime.Now; ', и это позже запутает систему. Это всего лишь предположение.

Между тем, я бы предположил, что ваши функции равенства и хэш-кода - это путь к территории избыточного убийства. Теперь я собираюсь предположить, что «ID» для классов Message и MessageThread должны быть уникальными, и в этом случае вы действительно можете упростить свою логику, и вам будет легче добраться до сути вашей проблемы, например так;

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

Очевидно, вы захотите сделать это и для других ваших классов. Преимущество в том, что меньше движущихся частей и, следовательно, меньше шансов на то, чтобы что-то пошло не так. Кроме того, тела сообщения, отправители и т. Д. Не нужны для определения уникальности сообщения.

0 голосов
/ 26 апреля 2011

Это нормально?

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

Я бы предпочел подход, который, если идентификатор равен, почтовые сообщения одинаковы:

return Id == other.Id;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...