Linq Distinct в определенном поле

Дано:

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

Как я могу вернуть Distinct записи только на идентификаторе?

Ответ 1

Вы можете написать IEqualityComparer, который сравнивает значения ID и передает его в перегруженный Queryable.Distinct метод, но поскольку это LINQ to SQL, он не будет поддерживаться в базе данных. Вам нужно будет добавить вызов метода AsEnumerable, чтобы он работал, но это не рекомендуется для больших объемов данных, потому что вы будете приносить данные вплоть до клиентской стороны. Если вы решите пойти по этому маршруту, у вас будет запрос, похожий на:

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

Другой вариант, который делает базу данных выполненной, состоит в группировке по ID и занимает первый элемент в каждой группе:

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

Ответ 2

Если вы хотите добавить возможность сделать это как метод расширения, здесь вызывается метод DistinctBy, который принимает в качестве источника и keySelector параметры и возвращает отдельный набор элементов. Он делает то же самое, что и второй запрос Ахмада, но выглядит немного красивее.

С#:
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

Затем назовите это:

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