2011-05-12 2 views
10

Dato:Linq distinta sul campo specifico

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

Come dovrei restituire i record distinto basato solo sul ID?

+2

Questo Q è un po 'come [Remove Duplicate sulla base di colonna del valore-LINQ] (http://stackoverflow.com/q/3446442/590956) – Sam

risposta

14

È possibile scrivere un IEqualityComparer che confronta i valori ID e passarlo nello overloaded Queryable.Distinct method, ma poiché questo è LINQ su SQL, non sarà supportato nel database. Dovresti aggiungere una chiamata allo AsEnumerable method per farlo funzionare, ma questo non è consigliato per grandi quantità di dati perché porterebbe i dati al lato client. Se si decide di seguire questa strada si finirà con una query simile a:

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

L'altra opzione, il che rende il database fare il lavoro, è quello di raggruppare da ID e prendere la prima voce di ogni gruppo:

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

Se si vuole aggiungere la capacità di fare questo come un metodo di estensione, ecco un metodo chiamato DistinctBy che prende nella fonte e keySelector come parametri e restituisce la distinta set elemento. Fa la stessa cosa della seconda query di Ahmad, ma sembra un po 'più carina in linea.

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 

quindi chiamare in questo modo:

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