IEnumerable.Except() not excluding

本文关键字:not excluding Except IEnumerable | 更新日期: 2023-09-27 17:55:06

我有两个数组。第一个保存所有成员,第二个保存所有已声明的成员。我试图使用except只获取未认领的成员,但结果数组包括所有成员(第一个数组的精确副本)。

var junior_handler_All = db2.junior_handler.Include(j => j.person).Include(j => j.status).ToArray();
var junior_handler_Claimed = db.junior_handler.Include(j => j.person).Include(j => j.status).ToArray();
var junior_handler_Unclaimed = junior_handler_All.Except(junior_handler_Claimed).ToArray();

我还尝试使用具有相同结果的where查询获取未认领的成员。

var junior_handler_Unclaimed = junior_handler_All.Where(i => !junior_handler_Claimed.Contains(i.Junior_Handler_ID.ToString()));

知道为什么这两个都不起作用吗?

IEnumerable.Except() not excluding

ExceptContains比较元素的方法是调用GetHashCode(),如果哈希值相等,则调用Equals来检查两个元素是否相等。

因此,如果您将此应用于没有自己的GetHashCode()Equals()实现的引用类型,则此比较将导致简单的引用相等性检查。

您可能不想比较对象的引用,而是要比较某种ID。所以你有两个选择:

你可以在你的类中重写GetHashCode()Equals():

public class Person
{
    public int ID { get; set; }
    public override bool Equals(object o)
    {
        return ID == (o as Person)?.ID;
    }
    public override int GetHashCode()
    {
        return ID;
    }
}

或者像这样实现IEqualityComparer<Person>:

public class Comparer : IEqualityComparer<Person>
{
    public bool Equals(Person x, Person y)
    {
        return x.ID == y.ID; // or whatever defines your equality
    }
    public int GetHashCode(Person obj)
    {
        return obj.ID; // or whatever makes a good hash
    }
}

并提供此比较器的实例到Except:

var junior_handler_Unclaimed =
     junior_handler_All.Except(junior_handler_Claimed, new Comparer()).ToArray();

你需要更新你的类来实现等价和/或重写Equals和GetHashCode。

引用:

MSDN on Except:

使用默认相等比较器比较值

,产生两个序列的集合差值。

MSDN默认相等比较器:

Default属性检查类型T是否实现了System。接口,如果是,则返回使用该实现的EqualityComparer。否则,它返回一个使用Object的重写的EqualityComparer。等号和对象。

提供的GetHashCode