There are several ways to achieve this.
You could pass
a custom IEqualityComparer<T>
implementation[
^] to
the Distinct
method[
^]:
public sealed class ErrorLogEqualityComparer : IEqualityComparer<ErrorLog>
{
public int GetHashCode(ErrorLog obj)
{
if (obj == null) return 0;
return StringComparer.Ordinal.GetHashCode(obj.ErrorGroupId)
^ StringComparer.Ordinal.GetHashCode(obj.ErrorDescription);
}
public bool Equals(ErrorLog left, ErrorLog right)
{
if (left == null) return right == null;
if (right == null) return false;
return StringComparer.Ordinal.Equals(left.ErrorGroupId, right.ErrorGroupId)
&& StringComparer.Ordinal.Equals(left.ErrorDescription, right.ErrorDescription);
}
}
List<ErrorLog> distinctList = _unprocessedErrors
.Distinct(new ErrorLogEqualityComparer())
.ToList();
You could use
the GroupBy
method[
^] to group your results by the key values, and then extract the first item from each group:
List<ErrorLog> distinctList = _unprocessedErrors
.GroupBy(e => new { e.ErrorGroupId, e.ErrorDescription }, (key, list) => list.First())
.ToList();
Or, you could use a custom
DistinctBy
method, such as the one provided by
the MoreLinq library[
^]:
public static class SetExtensions
{
private static IEnumerable<TSource> DistinctByIterator<TSource, TKey>(IEnumerable<TSource> source, Func<TSource, TKey> keySelector, IEqualityComparer<TKey> keyComparer)
{
var knownKeys = new HashSet<TKey>(keyComparer);
try
{
foreach (var item in source)
{
if (knownKeys.Add(keySelector(item)))
{
yield return item;
}
}
}
finally
{
knownKeys = null;
}
}
public static IEnumerable<TSource> DistinctBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, IEqualityComparer<TKey> keyComparer = null)
{
if (source == null) throw new ArgumentNullException("source");
if (keySelector == null) throw new ArgumentNullException("keySelector");
return DistinctByIterator(source, keySelector, keyComparer);
}
}
List<ErrorLog> distinctList = _unprocessedErrors
.DistinctBy(e => new { e.ErrorGroupId, e.ErrorDescription })
.ToList();