I have a method that processes a list of entities and checks if they are valid or not. Invalid entities are added to a HashSet. Later, I attempt to filter out these invalid entities from the original list, but the filtering doesn’t work correctly — invalid entities are still present in the final list.
I found an issue, fixed it, but I got warnings afterwards.
PersonSyncService.cs
protected override async Task Add(List<(PersonEntity dest, PersonSyncModel src)> entities)
{
var invalidEntities = new HashSet<(PersonEntity dest, PersonSyncModel src)>();
//Irrelevant code is removed from this post
//This is where the problem is. entitesToAdd needs to be 0 because invalidEntities and entities consist of same elements.
//For example, if the count of entities is 5, invalidEntities is also 5.
//entitiesToAdd should have no elements. But in this code, it would be 5.
var entitiesToAdd = entities.Where(entity => !invalidEntities.Contains(entity)).Select(e => e.dest).ToList();
await Repository.InsertAsync(entitiesToAdd);
//Rest of the code
}
Problem is, that PersonEntity inherits from EntityBase class. In which there is a custom implementation of Equals and GetHashCode. This is current version :
public abstract class EntityBase<TKey> : IEntity<TKey>, IEquatable<IEntity<TKey>>
{
public virtual TKey Id { get; set; }
// Custom equality comparison for IEntity<TKey>
public virtual bool Equals(IEntity<TKey> x, IEntity<TKey> y)
{
if (ReferenceEquals(x, y)) return true;
if (ReferenceEquals(x, null) || ReferenceEquals(y, null)) return false;
return EqualityComparer<TKey>.Default.Equals(x.Id, y.Id);
}
// Custom equality comparison with another IEntity<TKey>
public virtual bool Equals(IEntity<TKey> other)
{
if (ReferenceEquals(this, other)) return true;
if (ReferenceEquals(other, null)) return false;
return EqualityComparer<TKey>.Default.Equals(Id, other.Id);
}
// Equality comparison with an object
public override bool Equals(object obj)
{
if (ReferenceEquals(this, obj)) return true;
if (obj == null || obj.GetType() != GetType()) return false;
return Equals(obj as IEntity<TKey>);
}
// Consistent GetHashCode implementation
public override int GetHashCode()
{
return EqualityComparer<TKey>.Default.GetHashCode(Id);
}
// Implement IEqualityComparer's GetHashCode method
public int GetHashCode([DisallowNull] IEntity<TKey> obj)
{
return EqualityComparer<TKey>.Default.GetHashCode(obj.Id);
}
}
I have FIXED this issue but the fixed version of my code causes warnings.
Fixed EntityBase :
public abstract class EntityBase<TKey> : IEntity<TKey>, IEquatable<IEntity<TKey>>
{
public virtual TKey Id { get; set; }
public virtual bool Equals(IEntity<TKey> x, IEntity<TKey> y)
{
// Check whether the compared objects reference the same data
if (ReferenceEquals(x, y)) return true;
// Check whether any of the compared objects is null
if (ReferenceEquals(x, null) || ReferenceEquals(y, null)) return false;
// Check whether the objects' properties are equal.
return x.Id.Equals(y.Id);
}
public virtual bool Equals(IEntity<TKey> other)
{
if (ReferenceEquals(this, other)) return true;
if (ReferenceEquals(other, null)) return false;
return this.Id.Equals(other.Id);
}
public override bool Equals(Object obj)
{
if (obj == null) return false;
if (obj is not IEntity<TKey> entityObj) return false;
else return Equals(entityObj);
}
protected bool Equals(EntityBase<TKey> other)
{
return EqualityComparer<TKey>.Default.Equals(Id, other.Id);
}
public int GetHashCode([DisallowNull] IEntity<TKey> obj)
{
// Calculate the hash code for the object.
return obj.Id.GetHashCode();
}
}
But, now I am getting these warnings :