Support of POCO entities with custom Equals and GetHashCode implementations

EF6 will support POCO entities that have custom Equals or GetHashCode implementations. EF will instead use the default implementations. This is a continuation of efforts to have less requirements on the entity classes and to support a fairly common way of implementing the DDD aggregate pattern.

However there are some caveats:

  • 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<T> 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<T> 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);
        }
    }
  • Data binding through the Local property uses ObservableCollection which relies on the overridden Equals implementations. Make sure that in this case Equals only returns true if the key values are equal and that the key values are immutable at least during the data binding lifetime.

Last edited Apr 24, 2013 at 5:27 PM by ajcvickers, version 4