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 reco开发者_如何学运维rds based only on the ID?
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();
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.
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)
精彩评论