When Overriding GetHashCode(), Entity Framework 6 Throws Exception on SaveChanges()

c# entity-framework entity-framework-6

Question

Executing the following two lines

DBContext.DbSet.Remove(DBContext.DbSet.First(x => x.Id == someExistingId));
DBContext.SaveChanges();

results in the following exception being thrown on SaveChanges() when I override GetHashCode() on the DbSet entity type.

Adding a relationship with an entity which is in the Deleted state is not allowed.

I'm using a T4 Template to generate POCO objects and overriding GetHashCode() in a partial. If I comment out only the GetHashCode() override, the code executes as expected.

The GetHashCode() override just returns Id.GetHashCode(). Id is an int.

Is there some restriction related to overriding GetHashCode() with Entity Framework POCOs?

1
1
9/7/2017 12:27:26 AM

Accepted Answer

From the entity framework documentation:

  • You should still follow the guidelines (Eric Lippert has a great post on this) for implementing Equals and GetHashCode
  • If your hashcode/equality algorithm cannot guarantee immutability and uniqueness at all times then you need to make sure that your collection navigation properties use reference equality for comparisons. For HashSet pass System.Data.Entity.Infrastructure.ObjectReferenceEqualityComparer to the constructor (or create your own reference-based equality comparer, something like the snippet below should work). Do not use List as it will always use the overridden Equals method for methods like Remove.
public class Category
{
    public Category()
    {
        Products = new HashSet<Product>(new ObjectReferenceEqualityComparer());
    }

    public string CategoryId { get; set; }
    public string Name { get; set; }

    public virtual ICollection<Product> Products { get; set; }
}
[Serializable]
public sealed class ObjectReferenceEqualityComparer : IEqualityComparer<object>
{
    bool IEqualityComparer<object>.Equals(object x, object y)
    {
        return ReferenceEquals(x, y);
    }

    int IEqualityComparer<object>.GetHashCode(object obj)
    {
        return RuntimeHelpers.GetHashCode(obj);
    }
}
1
9/7/2017 1:05:07 AM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow