I am using this answer Difference between two lists to find a difference between two lists using Linq Except
. However, my objects in the lists are of generic type, so I wrote a Comparer for the generic types, then I pass it to Except method. However I receive the following error message:
Error CS1929 'List' does not contain a definition for 'Except' and the best extension method overload 'ParallelEnumerable.Except(ParallelQuery, ParallelQuery, IEqualityComparer)' requires a receiver of type 'ParallelQuery'
My call:
var differenceList = list1.Except(list2, new PropertyComparer<Guid>("ObjectId"));
And my comparer:
public class PropertyComparer<T> : IEqualityComparer<T>
{
private PropertyInfo _PropertyInfo;
public PropertyComparer(string propertyName)
{
_PropertyInfo = typeof(T).GetProperty(propertyName,
BindingFlags.GetProperty | BindingFlags.Instance | BindingFlags.Public);
if (_PropertyInfo == null)
{
throw new ArgumentException(
string.Format("{0} is not a property of type {1}.", propertyName, typeof(T)));
}
}
public int GetHashCode(T obj)
{
object propertyValue = _PropertyInfo.GetValue(obj, null);
if (obj == null) return 0;
return propertyValue.GetHashCode();
}
public bool Equals(T x, T y)
{
object xValue = _PropertyInfo.GetValue(x, null);
object yValue = _PropertyInfo.GetValue(y, null);
if (xValue == null)
{
return yValue == null;
}
return xValue.Equals(yValue);
}
}
And from the declaration of Except method in System.Linq
, which fits my comparer:
public static IEnumerable<TSource> Except<TSource>(
this IEnumerable<TSource> first,
IEnumerable<TSource> second,
IEqualityComparer<TSource> comparer
);
What am I doing wrong and how can I get it working?
UPDATE
list1
and list2
types:
List<Contact>
Where Contact
is
public class Contact : EntityBase
{
public Guid ContactId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public List<Email> Emails {get; set;}
}
EntityBase
is
public class EntityBase : IEntity
{
public IQueryable<T> GetDBEntities<T>(ApplicationDbContext db) where T : class
{
return db.Set<T>();
}
public List<T> GetLocalEntities<T>() where T : class
{
var localProperties = this.GetType().GetProperties();
foreach (var localProperty in localProperties)
{
var localPropertyValue = localProperty.GetValue(this);
if (localPropertyValue != null && localPropertyValue.IsGenericList() == true)
{
var localPropertyValueType = localPropertyValue.GetType(); // List<object>
var localPropertyValueTypeDecoupled = localPropertyValueType.GetGenericArguments().Single(); // List<T>
if (localPropertyValueTypeDecoupled == typeof(T))
{
return (List<T>)localPropertyValue;
}
}
}
throw new Exception("Entity Types Validation Error");
}
public void ProcessEntityReference<T>(ApplicationDbContext db) where T : class
{
// T is Email
var remoteList = this.GetDBEntities<T>(db).ToList();
var updatedList = GetLocalEntities<T>();
var toBeAdded = updatedList.Except(remoteList, new PropertyComparer<Guid>("ContactId"));
var toBeDeleted = new List<object>();
throw new NotImplementedException();
}
public void ProcessEntityReferences(ApplicationDbContext db)
{
this.ProcessEntityReference<Email>(db);
}
}