2

IEquatable (C#) の問題に直面しています。次のコードでわかるように、IEquatable を実装したクラスを取得しましたが、「Equals」メソッドに到達していません。私の目的は次のとおりです。データベースに日時列があり、「時間」の部分を考慮せずに日付のみを区別したいと考えています。

例: 12-01-2014 23:14 は 12-01-2014 18:00 と同じです。

namespace MyNamespace
{
    public class MyRepository
    {
        public void MyMethod(int id)
        {
            var x = (from t in context.MyTable
                     where t.id == id
                     select new MyClassDatetime()
                     {
                         Dates = v.Date
                     }).Distinct().ToList();
        }
    }


public class MyClassDatetime : IEquatable<MyClassDatetime>
{
    public DateTime? Dates { get; set; }

    public bool Equals(MyClassDatetime other)
    {
        if (other == null) return false;
        return (this.Dates.HasValue ? this.Dates.Value.ToShortDateString().Equals(other.Dates.Value.ToShortDateString()) : false);
    }

    public override bool Equals(object other)
    {
        return this.Equals(other as MyClassDatetime );
    }

    public override int GetHashCode()
    {
        int hashDate = Dates.GetHashCode();
        return hashDate;
    }
}
}

適切に機能させる方法や、必要なことを行うための他のオプションを知っていますか?? ありがとうございました!!

4

2 に答える 2

8

の実装はGetHashCode、目的の等価セマンティクスに対して正しくありません。これは、等しいと比較したい日付に対して異なるハッシュ コードを返すためです。これはバグです。

それを修正するには、次のように変更します

public override int GetHashCode()
{
    return Dates.HasValue ? Dates.Value.Date.GetHashCode() : 0;
}

また、同じ精神で更新する必要がありEqualsます。日付の文字列表現をいじるのはお勧めできません。

public bool Equals(MyClassDatetime other)
{
    if (other == null) return false;
    if (Dates == null) return other.Dates == null;
    return Dates.Value.Date == other.Dates.Value.Date;
}

更新: usrが非常に正確に指摘しているように、IQueryable で LINQ を使用しているため、プロジェクションとDistinct呼び出しはストア式に変換され、このコードはまだ実行されません。AsEnumerableこれを回避するには、中間呼び出しを使用できます。

var x = (from t in context.MyTable
         where t.id == id
         select new MyClassDatetime()
         {
             Dates = v.Date
         }).AsEnumerable().Distinct().ToList();
于 2014-07-08T14:44:13.403 に答える
0

返信ありがとうございますが、それでも私の問題は解決しません。

私は最終的にそれを行う方法を見つけましたが、IEquatable を使用しませんでした。

var x = (from t in context.MyTable where t.Id == id select EntityFunctions.CreateDateTime(t.Date.Value.Year, t.Date.Value.Month,t.Date.Value.Day, 0, 0, 0)).Distinct();

=)

于 2014-07-10T18:03:24.130 に答える