LINQ to Object Join运算符和相等

时间:2011-11-10 14:37:07

标签: c# .net linq

我有以下简单的LINQ to Object查询:

var accountsWithOpportunities = (from a in accountGetServices
                                 join o in opportunities on a equals o.Account
                                 select a).ToList();

此查询始终为0结果,但此查询不会:

var accountsWithOpportunities = (from a in accountGetServices
                                 join o in opportunities on a.Id equals o.Account.Id
                                 select a).ToList();
因此,我得出结论,我的平等操作做错了。 我有以下用于所有模型的抽象类:

public abstract class BaseModel<T> : BaseModel
        where T : class, IIdentifyable
    {
        public static bool operator ==(BaseModel<T> c1, BaseModel<T> c2)
        {
            T t1 = c1 as T;
            T t2 = c2 as T;

            if (object.ReferenceEquals(t1, t2)) return true;
            if (object.ReferenceEquals(t1, null)) return false;
            if (object.ReferenceEquals(t2, null)) return false;

            return c1.Equals(c2);
        }

        public static bool operator !=(BaseModel<T> c1, BaseModel<T> c2)
        {
            return !(c1 == c2);
        }
    }

    public abstract class BaseModel : IEquatable<BaseModel>
    {
        public bool Equals(BaseModel other)
        {
            if (other == null)
                return false;

            var identifyable1 = this as IIdentifyable;
            var identifyable2 = other as IIdentifyable;

            return identifyable1.Id == identifyable2.Id;
        }

        public override bool Equals(object obj)
        {
            return base.Equals(obj) && Equals(obj as BaseModel);
        }
    }

我在每个功能上放置了断点,以查看引擎盖下发生了什么,但没有一个被击中 我做错了什么?

3 个答案:

答案 0 :(得分:2)

public override bool Equals(object obj)
{
  return base.Equals(obj) && Equals(obj as BaseModel);
}

这部分似乎是错误的。 base.Equals调用object.ReferenceEquals,它总是(或者至少在大多数情况下)返回false,因此永远不会评估另一个表达式。

修改

另外,如前所述,GetHashCode被调用(你应该得到一个编译器警告,你已经覆盖了Equals但不是GetHashCode)。因此,更改GetHashCode以返回实体的Id,它应该开始工作。

答案 1 :(得分:0)

public override bool Equals(object obj)没有被击中?我看到你在这里调用object.Equals这将使它始终返回false。更好的实施方式是:

public override bool Equals(object obj)
{
    return this.Equals(obj as BaseModel);
}

答案 2 :(得分:0)

真正的解决方案是覆盖GetHashCode()以始终返回0。 然后所有的相等函数都被击中了 我不确定为什么或者有更好的方法来实现GetHashCode()