LINQ's Distinct() on a particular property
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
Distinct() removes duplicate elements based on the equality of the element type itself. When you want uniqueness based on only one property, the cleanest solution depends on your .NET version: modern code usually uses DistinctBy, while older code falls back to GroupBy or a custom comparer.
Why Plain Distinct() Is Not Enough
Given a class like this:
calling Distinct() on a list of Employee objects does not magically know that Id is the property you care about.
Unless Employee overrides equality appropriately, those objects are treated as different instances.
Modern Solution: DistinctBy
If you are on modern .NET, DistinctBy is the most direct answer.
This keeps the first element encountered for each distinct key value.
Older Fallback: GroupBy
If DistinctBy is unavailable, GroupBy is a readable fallback.
The effect is similar: group by the property, then choose one representative from each group.
This is often simpler than writing a whole comparer when you only need the logic in one place.
Custom Comparer for Reuse
If the same distinct-by-property rule appears throughout the codebase, a custom IEqualityComparer<T> can be worth the extra code.
Then:
This is useful when the equality rule is part of the domain and should be reused explicitly.
Do Not Override Equality Casually
You could override Equals and GetHashCode on the entity itself, but that changes equality for the whole application. That is only appropriate when the property truly defines the object's identity everywhere.
If Employee.Id is a database identity and that is your domain-wide notion of equality, overriding may be reasonable. If not, use DistinctBy, GroupBy, or a comparer instead of changing global object behavior.
Which Duplicate Survives
One subtle point is that property-based distinct operations typically keep the first item encountered for each key. That means order matters.
If you want "the newest record for each Id" rather than "the first record for each Id," sort first or choose the right group representative:
The property selector defines uniqueness, but the input order often determines which item is preserved.
Common Pitfalls
The biggest mistake is assuming Distinct() can infer which property should define equality. It cannot; it only knows about element equality.
Another issue is overriding Equals and GetHashCode just to satisfy one query. That can create surprising behavior everywhere else in the application.
Developers also forget that property-based distinct keeps one representative, not a merged record. If duplicates carry different non-key data, be deliberate about which one survives.
Finally, if DistinctBy is unavailable in your target framework, do not force awkward workarounds. GroupBy(...).Select(g => g.First()) is perfectly serviceable.
Summary
- Plain
Distinct()uses element equality, not a chosen property selector. - '
DistinctByis the cleanest modern way to remove duplicates by one property.' - '
GroupBy(...).Select(g => g.First())is a good fallback on older frameworks.' - Use a custom comparer when the rule should be reused across the codebase.
- Be explicit about which duplicate record you want to keep.

