2009-05-26 5 views
33

J'essaie de remplir une liste déroulante avec des compagnies pharmaceutiques, comme Bayer, Medley etc. Et, je reçois ces noms de DB et thèses les noms sont répétés dans DB, mais avec des ID différents. J'essaie d'utiliser Linq Distinct(), mais je ne veux pas utiliser le comparateur d'égalité. Y a-t-il un autre moyen?Linq Distinct() par nom pour remplir une liste déroulante avec le nom et la valeur

Ma liste déroulante doit être remplie avec l'identifiant et le nom de l'entreprise.

J'essaie quelque chose comme:

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

Cette montre les entreprises répétées dans ddl.

merci!

+0

Si une société apparaît plusieurs fois avec des ID différents et que vous souhaitez qu'elle n'apparaisse qu'une seule fois, quel identifiant doit être affiché? La première? Cela n'a pas d'importance? –

+0

L'identifiant est l'identité – AndreMiranda

Répondre

76

L'expression suivante sélectionne uniquement des sociétés distinctes et retourner la première occurence avec son identifiant.

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

Bonjour Daniel! C'était exactement ce dont j'avais besoin! Merci! :-) – AndreMiranda

+0

Juste parfait! :) – rafek

+0

quand je fais: dgvRecords.DataSource = (à partir de g dans dbContext.records, sélectionnez g) .GroupBy (g => g.ID) .Sélectionnez (g => g.FirstOrDefault()); J'obtiens: Message = La méthode spécifiée n'est pas supportée. Source = MySql.Data.Entity –

3

Des travaux distincts sur l'ensemble de la sélection. Si vous incluez c.codPartner dans select, et qu'il y a deux valeurs différentes de c.codPartner pour le même c.name, alors vous allez voir deux lignes avec le même c.name.

0

passez simplement dans votre propre comparateur à la méthode Distinct en utilisant l'une des autres surcharges.

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

Cela ne changera rien ... s'il y a plusieurs sociétés avec le même nom mais un identifiant différent, comment choisiriez-vous l'identifiant à utiliser? –

+0

Je suis d'accord - choisir l'identifiant serait un problème. Si vous voulez un ID spécifique pour chacun, l'utilisation d'un distinct avec un EqualityComparer ne serait probablement pas le chemin à parcourir. Aussi, gardez à l'esprit sur le downvote ici que la question originale ne dit rien sur la sélection d'un ID spécifique pour chaque élément dans les résultats distincts ... –

1

Si vous ne spécifiez pas un paramètre IEqualityComparer, alors il suffit d'utiliser Object.ReferenceEquals, qui examine les objets valeur GetHashKey. Pour les types anonymes, ils sont uniques.

Maintenant, résoudre ce problème est un peu délicat, car vous ne pouvez pas écrire un IEqualityComparer pour un type anonyme. Donc, vous MUCT créer un type réel pour le problème:

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 ne compare pas les hashcodes, il compare les références ... il ne retournera vrai que si les deux références pointent vers la même instance –

2

Je ne pense pas que vous pouvez le faire avec une classe anonyme, mais si vous avez créé un objet de données comme

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; } 
    } 

} 

vous pouvez créer un objet comparateur comme

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

désolé de demander, mais d'où vient le 'g'? – StarCub

+1

@StarCub Companies est un IEnumerable . GroupBy accepte cela et renvoie IEnumerable >. Chaque élément de Select est un IGrouping . J'ai utilisé un nom différent pour rendre la différence de type plus évidente. –

1

dISTINC utilisera GetHashCode si vous ne pas dire (via un IEqualityComparer) à utilise une autre méthode. Vous pouvez utiliser un EqualityComparer générique, comme ceci:

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 
} 

puis utiliser comme celui-ci (kindof)

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