0

I am trying to calculate the Difference between two list my list type has this structure :

public partial class Assistance
{

    public int Id { get; set; }
    public string AssistanceName { get; set; }
    public string AssistanceTell { get; set; }
}

and here is my query :

           List<Assistance> assistanceWithoutExpert;
            AssistanceJurorRepository assistanceJurorRepository = new AssistanceJurorRepository();

            List<Assistance> assistancesWithExpert = assistanceJurorRepository.FindBy(i => i.User.Permission == "Assistance").Select(i => i.Assistance).ToList();
            List<Assistance> AllAssitance = GetAll().ToList();
            assistanceWithoutExpert = AllAssitance.Except(assistancesWithExpert).ToList();
            return assistanceWithoutExpert;

As you can see i have a list that holds all assitances called AllAssitance and a list that hold assitances that has expert called assistancesWithExpert i need to calculate assistanceWithoutExpert.So but after executing the result is all records in AllAssitance why ?

Best regards

Ehsan Akbar
  • 6,977
  • 19
  • 96
  • 180
  • Just override `Equals` and `GetHashCode` methods with your own. – Tony Aug 27 '14 at 11:58
  • @Tony i am not familiar with these that you said .you mean i should overide that method in dbcontext ? – Ehsan Akbar Aug 27 '14 at 11:58
  • Have you overridden `Equals()` and `GetHashCode()` in `Assistance`? – flindeberg Aug 27 '14 at 11:59
  • @flindeberg no i don't – Ehsan Akbar Aug 27 '14 at 12:00
  • Be aware that overriding `Equals()` and `GetHashCode()` can be a bit tricky to get right. You might want to read these [guidelines and rules](http://blogs.msdn.com/b/ericlippert/archive/2011/02/28/guidelines-and-rules-for-gethashcode.aspx) first. But that's definitely the way to go. – Corak Aug 27 '14 at 12:03

2 Answers2

1

The comparison is done using the default equality comparer. From MSDN:

Produces the set difference of two sequences by using the default equality comparer to compare values.

You need to define a custom comparison by overriding GetHashCode and Equals.

The default equality comparer, Default, is used to compare values of the types that implement the IEqualityComparer generic interface. To compare a custom data type, you need to implement this interface and provide your own GetHashCode and Equals methods for the type.

In short, you need to add the following code to your class Assistence if you want to compare the instances through the Id property.

public override int GetHashCode() {
    return Id.GetHashCode();
}

public override bool Equals(obj otherInstance) {
    return (otherInstance is Assistence) && ((Assistence)otherInstance).Id == Id;
}

A note of warning though if you want to compare on some field that isn't unique. See this link.

Maarten
  • 22,527
  • 3
  • 47
  • 68
1

You need to use the overload which takes a comparer. It doesn't work out of the box with complex types.

public class AssistanceComparer: IEqualityComparer<Assistance>
{
    public bool Equals(Assistance x, Assistance y)
    {
        return x.ID == y.ID;
    }

    public int GetHashCode(Assistance assistance)
    {
        return assistance.ID.GetHashCode();
    }
}

Usage:

assistanceWithoutExpert = AllAssitance.Except(assistancesWithExpert, new AssistanceComparer()).ToList();
DGibbs
  • 14,316
  • 7
  • 44
  • 83
  • 1
    let me try this .thank you ,i should implement this in assitance class – Ehsan Akbar Aug 27 '14 at 12:02
  • Could you please give me some details about GetHashCode? – Ehsan Akbar Aug 27 '14 at 12:30
  • @EA This should be useful to you: [What's the role of GetHashCode in the IEqualityComparer in .NET?](http://stackoverflow.com/questions/4095395/whats-the-role-of-gethashcode-in-the-iequalitycomparert-in-net). – DGibbs Aug 27 '14 at 13:57