Do you ever have one of those ‘Doh’ days? One of those days where you spend like 6 hours trying to replicate a bug simply so you can debug it. One of those days you wish you could have back? Well I had one of those last week, let me explain.
Recently I was trying to debug an issue where when I would add an instance of an object to the db contenxt sometimes it would take it and sometimes it would not. I tried for hours to replicate the exact steps so I could narrow down the issue but was not able to. Here is what I was essentially doing.
dbContext.MyCollection.Add( instance1 );
dbContext.MyCollection.Add( instance2 );
dbContext.MyCollection.Add( instance3 );
(of course my logic was not like this in the actual code, but it did boil down to this)
At the end of my 3 adds I would do dbContext.MyCollection.Count and expect to see 3, but in almost ALL cases I would get a 1, color me perplexed. To make it even more perplexing for me is that after each .Add I would check .EntityState of the newly added instance and in EVERY case it was NEW. I would also hashcode for each instance to ensure they were different and as you may have guessed they were….. WTF
Fast forward a few more hours of my swearing like a drunk sailor, beating my head on my desk I decided to chat with a co-worker of mine whose knowledge in EF is order of magnitude larger than mine. Although he did not know the direct reason for my pain he did make a magic assertion which lead me to remember something I did a few weeks back. He said,
Well when you add an instance to the collection EF will essentially just check that object for equality versus all the other objects in the collection to make sure they were different.
The minute he finished that sentence the ‘ah F@CK’ bomb went off in my head. See a few weeks prior, during very early development of this feature I had this brilliant idea that I needed to override the .Equals() method on my entity objects (yea I know, that was dumb) so I did. However, as my logic matured over time the .Equals did not keep up because at some point I had realized that I did not need to override that but I was entirely to lazy to delete my overridden method, oh that came back to hurt.
As soon as I realized that this may be the issue I blew away the .Equals() along with my override of GetHashCode() (which actually was simply a pass through to the base implementation) and what do you know, everything simply worked.
The moral of the story here is that when dealing with EF (or any ORM for that matter) I would highly suggest you do not override the .Equals() on your objects, unless you like pain and suffering
till next time,
04-24-2012 4:46 AM