web-dev-qa-db-fra.com

Code Linq pour sélectionner un élément

Je me retrouve à écrire beaucoup de code comme celui-ci pour sélectionner un élément qui correspond

var item = (from x in Items where x.Id == 123 select x).First();

Y a-t-il une manière plus propre de le faire ou est-ce aussi concis que je vais l'avoir?

EDIT: aurait dû dire "Plus propre en utilisant la syntaxe linq". J'étais déjà au courant de la syntaxe lambda et ça commence à ressembler à ça, c'est en fait le seul moyen. J'ai quand même eu des informations utiles, alors merci à tous ceux qui ont répondu.

97
Mikey Hogarth

Tout dépend de la syntaxe de la requête linq. Vous pouvez utiliser les méthodes d’extension directement comme ceci:

var item = Items.First(i => i.Id == 123);

Et si vous ne voulez pas générer d'erreur si la liste est vide, utilisez FirstOrDefault qui renvoie la valeur par défaut du type d'élément (null pour les types de référence):

var item = Items.FirstOrDefault(i => i.Id == 123);

if (item != null)
{
    // found it
}

Single() et SingleOrDefault() peuvent également être utilisés, mais si vous lisez dans une base de données ou quelque chose qui garantit déjà l'unicité, cela ne me dérangerait pas car il faut parcourir la liste pour voir s'il y a des doublons et des jets . First() et FirstOrDefault() s'arrêtent au premier match, ils sont donc plus efficaces.

De la famille First() et Single(), voici où ils jettent:

  • First() - jette si vide/non trouvé, ne jette pas si dupliquer
  • FirstOrDefault() - retourne la valeur par défaut si vide/introuvable, ne jette pas si dupliqué
  • Single() - lève si vide/non trouvé, lève si la copie existe
  • SingleOrDefault() - retourne la valeur par défaut si vide/introuvable, jette s'il existe une copie
160
James Michael Hare

FirstOrDefault ou SingleOrDefault peut être utile, selon votre scénario et si vous souhaitez gérer la présence de zéro ou de plusieurs correspondances:

FirstOrDefault: renvoie le premier élément d'une séquence ou une valeur par défaut si aucun élément n'est trouvé.

SingleOrDefault: renvoie le seul élément d'une séquence ou une valeur par défaut si la séquence est vide. cette méthode lève une exception s'il y a plus d'un élément dans la séquence

Je ne sais pas comment cela fonctionne dans une requête 'from' de linq mais dans la syntaxe lambda cela ressemble à ceci:

var item1 = Items.FirstOrDefault(x => x.Id == 123);
var item2 = Items.SingleOrDefault(x => x.Id == 123);
15
stuartd

Juste pour faciliter la vie de quelqu'un, la requête linq avec l'expression lambda

(from x in Items where x.Id == 123 select x).FirstOrDefault();

aboutit à une requête SQL contenant select top (1).

10
Amal

Ce sont les méthodes préférées:

var item = Items.SingleOrDefault(x => x.Id == 123);

Ou

var item = Items.Single(x => x.Id == 123);
10
James Hill

Cela peut être mieux résumé à cela.

var item = Items.First(x => x.Id == 123);

Votre requête collecte actuellement tous les résultats (et il peut y en avoir plus d'un) dans l'énumérable, puis extrait le premier de that set, en effectuant plus de travail que nécessaire.

Single/SingleOrDefault valent la peine, mais uniquement si vous souhaitez parcourir l'ensemble de la collection et vérifier que la correspondance est unique en plus de la sélection de cette correspondance. First/FirstOrDefault prendra juste le premier match et partira, quel que soit le nombre de doublons existants.

7
Chris Hannon

Vous pouvez utiliser la syntaxe de la méthode d'extension:

var item = Items.Select(x => x.Id == 123).FirstOrDefault();

En dehors de cela, je ne sais pas à quel point vous pouvez être plus concis sans écrire vos propres méthodes d'extension spécialisées "First" et "FirstOrDefault".

3
wageoghe

Je vais vous dire ce qui a fonctionné pour moi:

int id = int.Parse(insertItem.OwnerTableView.DataKeyValues[insertItem.ItemIndex]["id_usuario"].ToString());

var query = user.First(x => x.id_usuario == id);
tbUsername.Text = query.username;
tbEmail.Text = query.email;
tbPassword.Text = query.password;

Mon identifiant correspond à la ligne que je veux interroger. Dans ce cas, il provient d'un radGrid, puis je l'ai utilisé pour interroger, mais cette requête renvoie une ligne. Vous pouvez ensuite affecter les valeurs que vous avez obtenues de la requête à textbox. , Je devais assigner ceux-ci à textbox.

1
G Jeny Ramirez