Linq Distinct на конкретном поле - PullRequest
10 голосов
/ 13 мая 2011

Дано:

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

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

Ответы [ 2 ]

14 голосов
/ 13 мая 2011

Вы можете написать 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();
8 голосов
/ 18 марта 2014

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

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

Тогда звоните так:

var s = (from p in operatorList.DistinctBy(x => x.ID)                       
         select p.ID, p.Name, p.Phone)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...