web-dev-qa-db-fra.com

Distinct dans Linq basé sur un seul champ de la table

J'essaie d'utiliser .distinct dans Linq pour obtenir un résultat basé sur un champ de la table (il n'est donc pas nécessaire de dupliquer entièrement les enregistrements de la table).

Je sais écrire la requête de base en utilisant distinct comme suit:

var query = (from r in table1
orderby r.Text
select r).distinct();

mais j'ai besoin de résultats où r.text n'est pas dupliqué.

106
Megha Jain

Essaye ça:

table1.GroupBy(x => x.Text).Select(x => x.FirstOrDefault());

Cela va regrouper la table par Text et utiliser la première ligne de chaque groupe pour obtenir des lignes où Text est distinct.

254
Daniel Hilgarth

MoreLinq a une méthode DistinctBy que vous pouvez utiliser:

Cela vous permettra de faire:

var results = table1.DistictBy(row => row.Text);

L'implémentation de la méthode (en l'absence de validation d'argument) est la suivante:

private static IEnumerable<TSource> DistinctByImpl<TSource, TKey>(IEnumerable<TSource> source,
    Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer)
{
    HashSet<TKey> knownKeys = new HashSet<TKey>(comparer);
    foreach (TSource element in source)
    {
        if (knownKeys.Add(keySelector(element)))
        {
            yield return element;
        }
    }
}
20
Servy

mais j'ai besoin de résultats où r.text n'est pas dupliqué

On dirait que tu veux ça:

table1.GroupBy(x => x.Text)
      .Where(g => g.Count() == 1)
      .Select(g => g.First());

Cela sélectionnera les lignes où la Text est unique.

12
Tim Schmelter

Il y a beaucoup de discussions autour de ce sujet.

Vous pouvez en trouver un ici :

Une des suggestions les plus populaires a été la méthode Distinct prenant une expression lambda comme paramètre, comme l'a souligné @Servy.

Anders Hejlsberg, architecte en chef du C #, a suggéré la solution ici . Expliquant également pourquoi l'équipe de conception du cadre a décidé de ne pas ajouter une surcharge de méthode Distinct qui prend un lambda.

3
TKharaishvili

La réponse de Daniel Hilgarth ci-dessus conduit à une exception System.NotSupported avec With Entity-Framework . Avec Entity-Framework , il doit être:

table1.GroupBy(x => x.Text).Select(x => x.FirstOrDefault());
3
Biraj Saha

D'après ce que j'ai trouvé, votre requête est généralement correcte. Il suffit de changer "select r" en "select r.Text", c'est tout et cela devrait résoudre le problème. Voici comment MSDN a documenté son fonctionnement.

Ex:

    var query = (from r in table1 orderby r.Text select r.Text).distinct();
2
Josh Parks
data.Select(x=>x.Name).Distinct().Select(x => new SelectListItem { Text = x });
1
bgS