c# exemple - Quand utiliser.FirstOrDefault avec LINQ?




cours example (13)

J'ai cherché autour et n'ai pas vraiment trouvé une réponse claire quant à quand vous voudriez employer. D' .First et quand vous voudriez employer. .FirstOrDefault avec LINQ.

  • Quand voudriez-vous utiliser. D' .First ? Seulement quand vous voulez attraper l'exception si aucun résultat n'est retourné?

    var result = List.Where(x => x == "foo").First();
    
  • Et quand voudriez-vous utiliser .FirstOrDefault ? Lorsque 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 Take?

    var result = List.Where(x => x == "foo").Take(1);
    

Answers

Premier:

  • Renvoie le premier élément d'une séquence
  • Lève exception: Il n'y a pas d'éléments dans le résultat
  • Utiliser quand: Lorsque plus d'un élément est attendu et que vous ne voulez que le premier

FirstOrDefault:

  • Renvoie le premier élément d'une séquence, ou une valeur par défaut si aucun élément n'est trouvé
  • Lève exception: Seulement si la source est nulle
  • Utiliser quand: Quand plus d'un élément est attendu et que vous voulez seulement le premier. Aussi, il est bon que le résultat soit vide

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


Tout d'abord, Take est une méthode complètement différente. Il retourne un IEnumerable<T> et pas un seul T , donc c'est fini.

Entre First et FirstOrDefault , vous devez utiliser First lorsque vous êtes sûr qu'un élément existe et, dans le cas contraire, il y a une erreur.

Par ailleurs, 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 .


J'utiliserais First() quand je sais ou attend que la séquence ait 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 que vous devrez vérifier s'il y avait 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 la vérification. (C'est une mauvaise pratique et cela pourrait nuire aux performances).

Enfin, la différence entre First() et Take() est que First() renvoie l'élément lui-même, tandis que Take() renvoie une séquence d'éléments qui contient exactement un élément. (Si vous passez 1 comme paramètre).



J'ai trouvé un site Web qui permet d'expliquer le besoin de FirstOrDefault
http://thepursuitofalife.com/the-linq-firstordefault-method-and-null-resultsets/
S'il n'y a aucun résultat à une requête, et que vous voulez appeler First () ou Single () pour obtenir une seule ligne ... Vous obtiendrez une exception "Sequence contains no elements".

Disclaimer: Je n'ai jamais utilisé LINQ, alors mes excuses si c'est loin de la réalité.


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 en utiliseriez potentiellement un parce que vous ne voulez pas provoquer une exception.

person = tmp.FirstOrDefault(new Func<Person, bool>((p) =>
{
    return string.IsNullOrEmpty(p.Relationship);
}));

.FirstOrDefault () retournera la valeur par défaut ( NULL pour tous les types de références) à la place.

Donc, si vous êtes prêt et prêt à gérer une exception possible, .First() est bien. Si vous préférez de toute façon vérifier la valeur de retour de! = Null, alors .FirstOrDefault() est votre meilleur choix.

Mais je suppose que c'est aussi un peu une préférence personnelle. Utilisez ce qui vous convient le mieux et adapte mieux votre style de codage.


Premier()

Lorsque vous savez que le résultat contient plus de 1 élément attendu et vous devriez seulement le premier élément de la séquence.

FirstOrDefault ()

FirstOrDefault () est comme First () sauf que, si aucun élément ne correspond à la condition spécifiée, il renvoie la valeur par défaut du type sous-jacent de la collection générique. Il ne lance pas InvalidOperationException si aucun élément n'a été trouvé. Mais la collection d'élément ou d'une séquence est nulle qu'elle lève une exception.


.First une exception quand il n'y a aucun résultat. .FirstOrDefault ne le fera pas, il retournera simplement soit null (types de référence) ou la valeur par défaut du type de valeur. (par exemple, comme 0 pour un int.) La question ici n'est pas quand vous voulez le type par défaut, mais plus: Êtes-vous prêt à gérer une exception ou gérer une valeur par défaut? Puisque les exceptions doivent être exceptionnelles, FirstOrDefault est préférable lorsque vous n'êtes pas sûr si vous allez obtenir des résultats hors de votre requête. Quand logiquement les données devraient être là, le traitement d'exception peut être considéré.

Skip() et Take() sont normalement utilisés lors de la configuration de la pagination dans les résultats. (Comme montrer les 10 premiers résultats, et les 10 suivants sur la page suivante, etc.)

J'espère que cela t'aides.


Une autre différence à noter est que si vous déboguez une application dans un environnement de production, vous n'aurez peut-être pas accès aux numéros de ligne. Il est donc difficile d'identifier quelle .First() particulière dans une méthode a jeté l'exception.

Le message d'exception n'inclura pas non plus les expressions Lambda que vous auriez pu utiliser, ce qui rendrait tout problème même 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));
}

Premier()

  1. Renvoie le premier élément d'une séquence.
  2. Il lance une erreur quand Il n'y a pas d'élément dans le résultat ou la source est nulle.
  3. vous devriez l'utiliser, Si plus d'un élément est attendu et vous voulez seulement le premier élément.

FirstOrDefault ()

  1. Renvoie le premier élément d'une séquence ou une valeur par défaut si aucun élément n'est trouvé.
  2. Il lance une erreur Seulement si la source est nulle.
  3. vous devriez l'utiliser, Si plus d'un élément est attendu et vous voulez seulement le premier élément. Aussi bien si le résultat est vide.

Nous avons une table UserInfos, qui a des enregistrements comme indiqué ci-dessous. Sur la base de ce tableau ci-dessous j'ai créé l'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 retourner cet enregistrement
ID: 1 Prénom: Manish Nom: 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 le 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 retourner cet enregistrement
ID: 1 Prénom: Manish Nom: 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 le 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 aucun enregistrement avec ID == 13. La valeur de retour est null

J'espère que cela vous aidera à comprendre quand utiliser First() ou FirstOrDefault() .


Ce type de fonction appartient aux opérateurs d'éléments. 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éments lorsque nous devons sélectionner un seul élément d'une séquence en fonction de la condition. Voici l'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 le sera par le biais d'une exception.

int résultat = items.Where (item => item == 2) .First ();

L'opérateur FirstOrDefault () renvoie le premier élément d'une séquence après avoir satisfait la condition. Si aucun élément n'est trouvé, il retournera la valeur par défaut de ce type.

int result1 = items.Where (item => item == 2) .FirstOrDefault ();


J'ai créé quelques méthodes d'extension (ci-dessous) donc vous n'avez pas à vous inquiéter si un IQueryable est déjà commandé ou non. Si vous souhaitez commander par plusieurs propriétés, procédez comme suit:

// We do not have to care if the queryable is already sorted or not. 
// The order of the Smart* calls defines the order priority
queryable.SmartOrderBy(i => i.Property1).SmartOrderByDescending(i => i.Property2);

Ceci est particulièrement utile si vous créez dynamiquement la commande, par exemple à partir d'une liste de propriétés à trier.

public static class IQueryableExtension
{
    public static bool IsOrdered<T>(this IQueryable<T> queryable) {
        if(queryable == null) {
            throw new ArgumentNullException("queryable");
        }

        return queryable.Expression.Type == typeof(IOrderedQueryable<T>);
    }

    public static IQueryable<T> SmartOrderBy<T, TKey>(this IQueryable<T> queryable, Expression<Func<T, TKey>> keySelector) {
        if(queryable.IsOrdered()) {
            var orderedQuery = queryable as IOrderedQueryable<T>;
            return orderedQuery.ThenBy(keySelector);
        } else {
            return queryable.OrderBy(keySelector);
        }
    }

    public static IQueryable<T> SmartOrderByDescending<T, TKey>(this IQueryable<T> queryable, Expression<Func<T, TKey>> keySelector) {
        if(queryable.IsOrdered()) {
            var orderedQuery = queryable as IOrderedQueryable<T>;
            return orderedQuery.ThenByDescending(keySelector);
        } else {
            return queryable.OrderByDescending(keySelector);
        }
    }
}




c# .net linq