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.
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 dupliquerFirstOrDefault()
- 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 existeSingleOrDefault()
- retourne la valeur par défaut si vide/introuvable, jette s'il existe une copieFirstOrDefault 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);
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)
.
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);
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.
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".
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.