J'ai cherché autour et je n'ai pas vraiment trouvé de réponse claire quant au moment où vous voulez utiliser .First
et quand vous voulez utiliser .FirstOrDefault
avec LINQ.
Quand voudriez-vous utiliser .First
? Seulement quand vous voudriez attraper l'exception si aucun résultat n'a été retourné?
var result = List.Where(x => x == "foo").First();
Et quand voudriez-vous utiliser .FirstOrDefault
? Quand vous voudriez toujours le type par défaut si aucun résultat?
var result = List.Where(x => x == "foo").FirstOrDefault();
Et d'ailleurs, qu'en est-il de prendre?
var result = List.Where(x => x == "foo").Take(1);
J'utiliserais First()
lorsque je saurais ou si je m'attendais à ce que la séquence comporte au moins un élément. En d'autres termes, lorsqu'il s'agit d'un événement exceptionnel, la séquence est vide.
Utilisez FirstOrDefault()
lorsque vous savez qu'il vous faudra vérifier s'il y a un élément ou non. En d'autres termes, quand il est légal que la séquence soit vide. Vous ne devez pas compter sur la gestion des exceptions pour le contrôle. (C'est une mauvaise pratique et peut nuire aux performances).
Enfin, la différence entre First()
et Take(1)
est que First()
renvoie l'élément lui-même, tandis que Take(1)
renvoie une séquence d'éléments contenant exactement un élément.
.First
lève une exception lorsqu'il n'y a aucun résultat. .FirstOrDefault
ne le fera pas, il renverra simplement soit null (types de référence), soit la valeur par défaut du type de valeur. (par exemple, comme 0
pour un int.) La question ici n'est pas de savoir quand vous voulez le type par défaut, mais plutôt: voulez-vous gérer une exception ou une valeur par défaut? Comme les exceptions doivent être exceptionnelles, FirstOrDefault
est préférable si vous n'êtes pas sûr d'obtenir des résultats de votre requête. Lorsque logiquement les données doivent être là, la gestion des exceptions peut être envisagée.
Skip()
et Take()
sont normalement utilisés lors de la configuration de la pagination dans les résultats. (Comme si vous montriez les 10 premiers résultats et les 10 suivants à la page suivante, etc.)
J'espère que cela t'aides.
.First()
lève une exception s'il n'y a pas de ligne à retourner, alors que .FirstOrDefault()
renvoie la valeur par défaut (NULL
pour tous les types de référence).
Donc, si vous êtes prêt et disposé à gérer une exception possible, .First()
est bon. Si vous préférez quand même vérifier la valeur de retour pour != null
, alors .FirstOrDefault()
est votre meilleur choix.
Mais je suppose que c'est aussi une préférence personnelle. Utilisez ce qui vous convient le mieux et correspond le mieux à votre style de codage.
First ()
FirstOrDefault ()
Nous avons une table UserInfos, qui contient certains enregistrements, comme indiqué ci-dessous. Sur la base de ce tableau ci-dessous, j'ai créé un exemple ...
Comment utiliser First ()
var result = dc.UserInfos.First(x => x.ID == 1);
Il n'y a qu'un seul enregistrement où ID == 1. Devrait renvoyer cet enregistrement.
ID: 1 Prénom: Manish Nom de famille: Dubey Email: [email protected]
var result = dc.UserInfos.First(x => x.FName == "Rahul");
Il existe plusieurs enregistrements où FName == "Rahul". Le premier enregistrement devrait être de retour.
ID: 7 Prénom: Rahul Nom de famille: Sharma Email: [email protected]
var result = dc.UserInfos.First(x => x.ID ==13);
Il n'y a pas d'enregistrement avec ID == 13. Une erreur devrait se produire.
InvalidOperationException: la séquence ne contient aucun élément
Comment utiliser FirstOrDefault ()
var result = dc.UserInfos.FirstOrDefault(x => x.ID == 1);
Il n'y a qu'un seul enregistrement où ID == 1. Devrait renvoyer cet enregistrement.
ID: 1 Prénom: Manish Nom de famille: Dubey Email: [email protected]
var result = dc.UserInfos.FirstOrDefault(x => x.FName == "Rahul");
Il existe plusieurs enregistrements où FName == "Rahul". Le premier enregistrement devrait être de retour.
ID: 7 Prénom: Rahul Nom de famille: Sharma Email: [email protected]
var result = dc.UserInfos.FirstOrDefault(x => x.ID ==13);
Il n'y a pas d'enregistrement avec ID == 13. La valeur de retour est null
J'espère que cela vous aidera à comprendre quand utiliser First()
ou FirstOrDefault()
.
Tout d'abord, Take
est une méthode complètement différente. Il retourne un IEnumerable<T>
et pas un seul T
, c'est donc fini.
Entre First
et FirstOrDefault
, vous devez utiliser First
lorsque vous êtes sûr qu'un élément existe et s'il ne le fait pas, il y a une erreur.
En passant, si votre séquence contient des éléments default(T)
(par exemple, null
) et que vous devez faire la distinction entre être vide et le premier élément étant null
, vous ne pouvez pas utiliser FirstOrDefault
.
Première:
FirstOrDefault:
De: http://www.technicaloverload.com/linq-single-vs-singleordefault-vs-first-vs-firstordefault/
Une autre différence à noter est que, si vous déboguez une application dans un environnement de production, vous n’avez peut-être pas accès aux numéros de ligne. Il peut donc être difficile d’identifier l’instruction .First()
dans une méthode générée par l’exception.
Le message d'exception n'inclura pas non plus d'expressions Lambda que vous auriez pu utiliser, ce qui rendrait tout problème encore plus difficile à déboguer.
C'est pourquoi j'utilise toujours FirstOrDefault()
même si je sais qu'une entrée nulle constituerait une situation exceptionnelle.
var customer = context.Customers.FirstOrDefault(i => i.Id == customerId);
if (customer == null)
{
throw new Exception(string.Format("Can't find customer {0}.", customerId));
}
First ()
Lorsque vous savez que le résultat contient plus d'un élément attendu, vous ne devez utiliser que le premier élément de la séquence.
FirstOrDefault ()
FirstOrDefault () est juste comme First () sauf que si aucun élément ne correspond à la condition spécifiée, il retourne la valeur par défaut du type sous-jacent de collection générique. Il ne lève pas InvalidOperationException si aucun élément n'est trouvé. Mais la collection d'élément ou une séquence est nulle qu'elle ne lève une exception.
J'ai trouvé un site Web qui apparait pour expliquer la nécessité de FirstOrDefault
http://thepursuitofalife.com/the-linq-firstordefault-method-and-null-resultsets/
S'il n'y a aucun résultat dans une requête et que vous souhaitez appeler First () ou Single () pour obtenir une seule ligne ... Vous obtiendrez une exception "La séquence ne contient aucun élément".
Déni de responsabilité: Je n'ai jamais utilisé LINQ, donc mes excuses si cela est loin du compte.
Ce type de fonction appartient aux opérateurs d'élément. Certains opérateurs d'éléments utiles sont définis ci-dessous.
Nous utilisons des opérateurs d'élément lorsque nous devons sélectionner un seul élément dans une séquence en fonction d'une certaine condition. Voici un exemple.
List<int> items = new List<int>() { 8, 5, 2, 4, 2, 6, 9, 2, 10 };
L'opérateur First () renvoie le premier élément d'une séquence après avoir satisfait à la condition. Si aucun élément n'est trouvé, il lève une exception.
int result = items.Where (item => item == 2) .First ();
L'opérateur FirstOrDefault () renvoie le premier élément d'une séquence une fois la condition remplie. Si aucun élément n'est trouvé, il renvoie la valeur par défaut de ce type.
int result1 = items.Where (item => item == 2) .FirstOrDefault ();
someList.First(); // exception if collection is empty.
someList.FirstOrDefault(); // first item or default(Type)
Lequel utiliser? Cela doit être décidé par la logique métier et non par la crainte d'une exception/d'un échec du programme.
Par exemple, si la logique métier indique que nous ne pouvons avoir aucune transaction aucun jour ouvrable (supposons simplement). Ensuite, vous ne devriez pas essayer de gérer ce scénario avec une programmation intelligente. J'utiliserai toujours First () sur cette collection et laisserai le programme échouer si quelque chose d'autre bousille la logique métier.
Code:
var transactionsOnWorkingDay = GetTransactionOnLatestWorkingDay();
var justNeedOneToProcess = transactionsOnWorkingDay.First(): //Not FirstOrDefault()
J'aimerais voir d'autres commentaires à ce sujet.
Ok laissez-moi donner mes deux cents. First/Firstordefault sont pour lorsque vous utilisez le second constructeur. Je ne vais pas expliquer ce que c'est, mais c'est quand vous utiliseriez potentiellement toujours un parce que vous ne voulez pas provoquer une exception.
person = tmp.FirstOrDefault(new Func<Person, bool>((p) =>
{
return string.IsNullOrEmpty(p.Relationship);
}));