I'm trying to exclude entities to be added to database if they already exist there. So I decided newBillInstances.Except(dbContext.BillInstances)
would be best approach for that. However it doesn't work at all (no entities are excluded) though for List<string>
it works perfectly.
I read this discussion and actual decription of .Except()
in MSDN. It states the class to be used in .Except()
should implement IEqualityComparer<T>
to use default comparer.
Actually the MSDN article doesn't fully describe process of comparison of two instances. I still don't get why both Equals() and GetHashObject() have to be overridden.
I have implemented IEqualityComparer<BillInstance>
interface and put break points in boths methods, but while calling .Except(IEnumerable)
it's not used. Only when I changed to .Except(IEnumerable, new BillInstanceComparer())
I've cough break in GetHashCode()
but no breaks where in Equals()
.
Then I have implemented IEqualityComparer<BillInstance>
right in BillInstance
class and expected it would be used while using .Except(IEnumerable)
but breaks weren't hit in both methods.
So I've got two questions:
.Except(IEnumerable)
?Equals()
isn't used at all? Is it used only in case hash codes of two instances are same?Because the Equals()
is used only if two objects have the same GetHashCode()
. If there are no objects that have the same GetHashCode()
then there is no chance of using the Equals()
.
Internally the Except()
uses a Set<>
(you can see it here), that is an internal class that you should consider to be equivalent to HashSet<>
. This class uses the hash of the object to "index" them, then uses the Equals()
to check if two objects that have the same hash are the same or different-but-with-the-same-hash.
Link to other relevant answer: https://stackoverflow.com/a/371348/613130
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With