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?
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);
}
}