IEquatable breaks loading of Entity Framework entities

c# entity-framework entity-framework-6 equality iequatable

Question

To see whether there are any variations between the records, I want to compare them.

Person table:

ID    Name          Address
--------------------------------
1     John Smith    123 A Street
2     John Smith    123 A Street
3     John Smith    234 B Street

Record 1 and Record 2 are "equivalent." Records 2 and 3 "do not equal" each other.

I've done it.IEquatable based onPerson as shown.

public static bool operator ==(Person p1, Person p2)
{
    if (System.Object.ReferenceEquals(p1, p2)) return true;

    return p1.Equals(p2);
}

public static bool operator !=(Person p1, Person p2)
{
    return !(p1== p2);
}

public bool Equals(Person other)
{
    if (System.Object.ReferenceEquals(this, other)) return true;

    if (Name != other.Name) return false;
    if (Address != other.Address) return false;

    return true;
}

public override bool Equals(object obj)
{
    Person person = obj as Person;
    if (person == null) return false;

    return Equals(person);
}

public override int GetHashCode()
{
    unchecked
    {
        int hash = (int)2166136261;
        hash = hash * 25165843 ^ (Name != null ? Name .GetHashCode() : 0);
        hash = hash * 25165843 ^ (Address != null ? Address.GetHashCode() : 0);

        return hash;
    }
}

Problem is, when thePersons A navigational property's ICollection is realized. It lacks records that are "equivalent" to one another (ie a single John Smith 123 A Street record is returned). I'm assuming this is the case because different entities are those that have unique primary keys by default. It assumes both records are the same entity by overriding equals.

Screenshot showingAddresses in place ofPersons (Top of page withIEquatable (Bottom is absent)enter image description here

//Addresses Definition (generated code)
public virtual ICollection<Address> Addresses { get; set; }

How can I balance EF's requirement for object-level equality with my desire for logical equality?

1
3
1/14/2015 9:47:35 PM

Accepted Answer

ZZZ_tmp
5
1/14/2015 10:24:08 PM

Popular Answer

IEquatable and IEqualityComparer are ideas that are essentially exclusive to LINQ to objects. Any definition of "equality" defined in this manner cannot be practically translated into SQL by EF, hence it is unable to carry out the necessary activities.

Simply group the things based on those values, then choose one item from each group, to get separate items based on specific fields in a method that can be translated into SQL:

var query = context.Table.GroupBy(row => new
    {
        row.Name,
        row.Address,
    })
    .Select(group => group.FirstOrDefault());


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