web-dev-qa-db-fra.com

Quand utiliser .Premier et quand utiliser .FirstOrDefault avec LINQ?

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);
    
780
Metro Smurf

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.

769
driis

.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.

264
Jeroen Landheer

.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.

111
marc_s

First ()

  1. Retourne le premier élément d'une séquence.
  2. Il renvoie une erreur lorsqu'il n'y a aucun élément dans le résultat ou que la source est null.
  3. vous devriez l'utiliser, si plus d'un élément est attendu et que vous ne voulez que le premier élément.

FirstOrDefault ()

  1. Retourne le premier élément d'une séquence ou une valeur par défaut si aucun élément n'est trouvé.
  2. Il génère une erreur uniquement si la source est null.
  3. vous devriez l'utiliser, si plus d'un élément est attendu et que vous ne voulez que le premier élément. Aussi bien si le résultat est vide.

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 ...

UserInfo Table

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().

63
Mukesh Kumar

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.

19
Mehrdad Afshari

Première:

  • Retourne le premier élément d'une séquence
  • Exception Throws: il n'y a aucun élément dans le résultat
  • Utiliser quand: quand plus d'un élément est attendu et que vous voulez seulement le premier

FirstOrDefault:

  • Retourne le premier élément d'une séquence ou une valeur par défaut si aucun élément n'est trouvé
  • Exception levée: uniquement si la source est null
  • Utiliser quand: Quand plus d'un élément est attendu et que vous ne voulez que le premier. De plus, le résultat doit être vide

De: http://www.technicaloverload.com/linq-single-vs-singleordefault-vs-first-vs-firstordefault/

13
user2051770

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));
}
9
Kye

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.

4
Nimesh khatri

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.

3
NULL

Ce type de fonction appartient aux opérateurs d'élément. Certains opérateurs d'éléments utiles sont définis ci-dessous.

  1. First/FirstOrDefault
  2. Last/LastOrDefault
  3. Single/SingleOrDefault

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 ();

3
Sheo Dayal Singh
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.

2
Manish Basantani

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);
}));
1
Arian