2009-05-26 5 views
33

Ich versuche, eine Dropdown-Liste mit pharmazeutischen Unternehmen, wie Bayer, Medley usw. zu füllen. Und ich bekomme diese Namen von DB und Thesen Namen werden in DB wiederholt, aber mit unterschiedlichen IDs.Linq Distinct() nach Name zum Auffüllen einer Dropdown-Liste mit Name und Wert

Ich versuche Linq Distinct() zu verwenden, aber ich möchte nicht den Gleichheitsvergleich verwenden. Gibt es eine andere Art und Weise?

Meine Dropdown-Liste muss mit der ID und dem Namen der Firma ausgefüllt werden.

Ich versuche, so etwas wie:

var x = _partnerService 
      .SelectPartners() 
      .Select(c => new {codPartner = c.codPartner, name = c.name}) 
      .Distinct(); 

Diese wiederholte Unternehmen in DDL zeigt.

danke!

+0

Wenn ein Unternehmen mehrere Male mit unterschiedlichen IDs auftaucht und nur einmal angezeigt werden soll, welche ID sollte angezeigt werden? Der Erste? Ist das egal? –

+0

Die ID ist die Identität – AndreMiranda

Antwort

76

Der folgende Ausdruck wird nur verschiedene Unternehmen auswählen und das erste Vorkommen mit seiner ID zurück.

partnerService.SelectPartners().GroupBy(p => p.Name).Select(g => g.First()); 
+0

Hallo Daniel! Das war genau das, was ich brauchte! Vielen Dank! :-) – AndreMiranda

+0

Einfach perfekt! :) – rafek

+0

wenn ich tue: dgvRecords.DataSource = (aus g in dbContext.records g) auswählen. GroupBy (g => g.ID) .Wählen (g => g.FirstOrDefault()); Ich bekomme: Message = Angegebene Methode wird nicht unterstützt. Quelle = MySql.Data.Entity –

3

Deutlich funktioniert auf der gesamten Auswahl. Wenn Sie c.codPartner in das select einfügen und es zwei verschiedene Werte von c.codPartner für denselben c.name gibt, dann sehen Sie zwei Zeilen mit demselben c.name.

0

übergeben Sie einfach Ihren eigenen Vergleich zu der Distinct-Methode mit einer der anderen Überladungen.

(extension) IQueryable<T> IQueryable<T>.Distinct(IEqualityComparer<T> comparer) 
+0

Es wird nichts ändern ... wenn es mehrere Firmen mit dem gleichen Namen aber unterschiedlicher ID gibt, wie würden Sie die ID wählen? –

+0

ich stimme zu - die Wahl der ID wäre ein Problem. Wenn Sie für jede eine bestimmte ID möchten, wäre die Verwendung eines distinct mit einem EqualityComparer wahrscheinlich nicht der richtige Weg. Denken Sie auch daran, dass die ursprüngliche Frage nichts über die Auswahl einer bestimmten ID für jedes Element in den einzelnen Ergebnissen aussagte ... –

1

Wenn Sie keinen IEqualityComparer Parameter angeben, dann wird es nur Object.ReferenceEquals verwenden, die an den Objekten GetHashKey Wert sieht. Für anonyme Typen sind sie eindeutig.

Jetzt ist das Lösen ein wenig schwierig, da Sie einen IEqualityComparer für einen anonymen Typ nicht schreiben können. So MUCT Sie einen echten Typen für das Problem schaffen:

class Partner 
{ 
    public int codPartner {get; set;} 
    public string name {get; set;} 
    public override int GetHashCode() { return name .GetHashCode();} 
} 

var x = _partnerService.SelectPartners() 
     .Select(c => new Partner {codPartner = c.codPartner, name = c.name}) 
     .Distinct(); 
+0

ReferenceEquals vergleicht keine Hashcodes, vergleicht Referenzen ... es gibt nur dann true zurück, wenn die beiden Referenzen auf die gleiche Instanz verweisen –

2

Das glaube ich nicht, dass Sie diese mit einer anonymen Klasse zu tun, aber wenn Sie ein Datenobjekt wie

erstellt
class Foo 
{ 
    private int _ID; 

    public int ID 
    { 
     get { return _ID; } 
     set { _ID = value; } 
    } 
    private string _Name; 

    public string Name 
    { 
     get { return _Name; } 
     set { _Name = value; } 
    } 

} 

Sie könnten erstellen ein Vergleich Objekt wie

class FooComparer : IEqualityComparer<Foo> 
{ 


    public bool Equals(Foo x, Foo y) 
    { 
     return x.Name == y.Name; 
    } 

    public int GetHashCode(Foo obj) 
    { 
     return obj.GetHashCode(); 
    } 

} 
17
var distinctCompanies = Companies 
    .GroupBy(c => c.CompanyName) 
    .Select(g => g.First()); 
+0

Entschuldigung, aber wo kommt das 'g' her? – StarCub

+1

@StarCub Companies ist ein IEnumerable . GroupBy akzeptiert das und gibt IEnumerable > zurück. Jedes Element in der Auswahl ist ein IGrouping . Ich benutzte einen anderen Namen, um den Unterschied in der Art deutlicher zu machen. –

1

bezeichnendes wird GetHashCode verwenden, wenn Sie es dont sagen (über ein IEqualityComparer) zu Verwenden Sie eine andere Methode. Sie könnten eine generische EqualityComparer wie folgt verwenden:

public class GenericEqualityComparer<T> : IEqualityComparer<T> 
{  
    private Func<T, T, Boolean> comparer;  

    public GenericEqualityComparer(Func<T, T, Boolean> comparer)  
    {   
     this.comparer = comparer;  
    }  

    #region IEqualityComparer<T> Implementation 

    public bool Equals(T x, T y)  
    {   
     return comparer(x, y);  
    }  

    public int GetHashCode(T obj)  
    { 
     return obj.GetHashCode(); 
    }  

    #endregion 
} 

und dann wie diese (kindof) verwenden

public static IEqualityComparer<YourType> MyComparer 
{ 
    get 
    { 
     return new GenericEqualityComparer<YourType>((x, y) => 
     { 
      return x.name.Equals(y.name); 
     }); 
     } 
}