0

Google Mail スタイルに近い PM システムを使用しています。つまり、メッセージは会話にグループ化されます。ユーザーがメッセージを受信すると、受信トレイに表示されます。また、このユーザーが誰かにメッセージを送信し、その人が返信を返すと、このメッセージも受信トレイに表示されます。

一部のメッセージは両方のクエリで取得され、最終的に 1 つのリストにグループ化されます。リスト C# から重複を削除する際に Jon Skeet が行ったことを実行して、重複を削除しようとしましたが、それでも重複が発生し続けます。これが私のコードです:

更新しました:

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 スレッド = (GetReplies(user, c.Id).Count() > 0 を選択する tmp の c から 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

削除されていない重複メッセージの例を提供せずに、等値チェック コードでの「DateTime」の使用が原因である可能性が高いと推測します。非常に一般的で、' 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 に答える
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 メソッドです。DTO をキャッチするために equals をオーバーロードしました。デフォルトでは、両方のオブジェクトで GetHashcode の結果が比較されます。オーバーロードされたバージョンはハッシュコードを比較しないため、実際には正しい実装のように見えますが、冗長になります。

編集 2 (投稿のコード変更に応じて): 投稿の下部にあるコード セクションが書式設定されていないため、わかりにくいですが、最後から 2 行目:

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

これは何もしません。2 つをマージします。

return threads.Distinct().ToList();
于 2011-04-26T13:28:18.423 に答える
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 に答える