John S
John S

Reputation: 8331

Linq Distinct on specific field

Given:

var s = (from p in operatorList                       
    select p.ID, p.Name,p.Phone)

How would I return the Distinct records based only on the ID?

Upvotes: 11

Views: 22585

Answers (2)

KyleMit
KyleMit

Reputation: 29909

If you wanted to add the ability to do this as an extension method, here's a method called DistinctBy which takes in the source and keySelector as parameters and returns the distinct item set. It does the same thing as Ahmad's second query, but looks a little prettier inline.

C#:
public static IEnumerable<TSource> DistinctBy<TSource, TKey>(
                                this IEnumerable<TSource> source, 
                                Func<TSource, TKey> keySelector)
{
    return source.GroupBy(keySelector).Select(i => i.First());
}
VB:
<Extension()>
Public Function DistinctBy(Of TSource, TKey)(
                    ByVal source As IEnumerable(Of TSource),
                    ByVal keySelector As Func(Of TSource, TKey))
                    As IEnumerable(Of TSource)

    Return source.GroupBy(keySelector).Select(Function(i) i.First())
End Function

Then call like this:

var s = (from p in operatorList.DistinctBy(x => x.ID)                       
         select p.ID, p.Name, p.Phone)

Upvotes: 9

Ahmad Mageed
Ahmad Mageed

Reputation: 96477

You could write an IEqualityComparer that compares the ID values and pass it into the overloaded Queryable.Distinct method, but since this is LINQ to SQL it won't be supported on the database. You would have to add a call to the AsEnumerable method to get it working, but this isn't recommended for large amounts of data because you would be bringing the data down to the client side. If you decide to go that route you will end up with a query similar to:

var query = dc.Operators.AsEnumerable().Distinct(new OperatorEqualityComparer());

The other option, which makes the database do the work, is to group by ID and take the first item in each group:

var query = from p in dc.Operators
            group p by p.ID into groups
            select groups.First();

Upvotes: 14

Related Questions