Question

Our code base currently has the following EqualityComparer.

    public static IEnumerable<TSource> Exclude<TSource, TKey>(this IEnumerable<TSource> first,
                                                              IEnumerable<TSource> second,
                                                              Func<TSource, TKey> keySelector,
                                                              IEqualityComparer<TKey> comparer = null)
    {
        comparer = comparer ?? EqualityComparer<TKey>.Default;
        var set = new HashSet<TKey>(second.Select(keySelector), comparer);
        return first.Where(item => set.Add(keySelector(item)));
    }

And we use it like this.

// Take the current model and remove all items currently in the database... This leaves us with only records that need to be added.
var userBooksToAdd = model.UserBooks.Exclude(currentUserBooksFromDatabase, d => d.Id).ToList();

We now have the need to compare against two fields in the database where there is a COMPOSITE UNIQUE

Basically

if(currentBooksFromDatabase.BookId == model.BookId && 
   currentBooksFromDatabase.UserId == model.Id)

I'm hoping to create an Exclude overload, but I'm really in over my head with the EqualityComparer

Was it helpful?

Solution

Use an anonymous object:

var userBooksToAdd = model.UserBooks.Exclude(currentUserBooksFromDatabase, 
    d => new{ d.Id, d.BookId }).ToList();

Note that anonymous objects will not use the Equals and GetHashCode implementations defined in object. They override them to do a memberwise comparison of each of the fields, so this will work as expected.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top