【问题标题】:IEquatable doesnt call Equals methodIEquatable 不调用 Equals 方法
【发布时间】:2014-07-08 14:41:27
【问题描述】:

我遇到了 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;
    }
}
}

你知道我怎样才能让它正常工作或其他选项来做我需要的吗? 谢谢!!

【问题讨论】:

标签: c# entity-framework datetime distinct iequatable


【解决方案1】:

您对 GetHashCode 的实现对于所需的相等语义不正确。这是因为它会为您想要比较相等的日期返回不同的哈希码 which is a bug

要修复它,请将其更改为

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 very correctly points out,由于您在 IQueryable 上使用 LINQ,因此投影和 Distinct 调用将被转换为存储表达式,并且此代码仍不会运行。要解决这个问题,您可以使用中间 AsEnumerable 调用:

var x = (from t in context.MyTable
         where t.id == id
         select new MyClassDatetime()
         {
             Dates = v.Date
         }).AsEnumerable().Distinct().ToList();

【讨论】:

  • 这段代码不会被调用,因为他正在执行一个EF查询。
  • @usr:它会被调用就好了。查询结果被投射到MyClassDatetime 实例中,.Distinct() 发生在之后。
  • 不过,这是 Queryable.Distinct。将被翻译。
  • @usr:天哪。你说的对。我已经编辑了答案来解决这个问题。
【解决方案2】:

感谢回复,但它仍然没有解决我的问题。

我终于找到了一种方法,但不使用 IEquatable。

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

=)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-04-24
    • 2012-03-08
    • 1970-01-01
    • 2011-09-11
    • 1970-01-01
    • 2018-08-02
    • 2011-12-27
    • 1970-01-01
    相关资源
    最近更新 更多