c# tutorial - Quando utilizzare.Prima e quando utilizzare.FirstOrDefault con LINQ?




api methods (13)

Prima di tutto, Take è un metodo completamente diverso. Restituisce un IEnumerable<T> e non un singolo T , quindi è fuori.

Tra First e FirstOrDefault , dovresti usare First quando sei sicuro che esista un elemento e, in caso contrario, c'è un errore.

A proposito, se la sequenza contiene elementi default(T) (ad es. null ) e devi distinguere tra essere vuoto e il primo elemento essere null , non puoi utilizzare FirstOrDefault .

Ho cercato in giro e non ho ancora trovato una risposta chiara su quando avresti voluto utilizzare. .First e quando avresti voluto usare .FirstOrDefault con LINQ.

  • Quando vorresti usare .First ? Solo quando vuoi recuperare l'eccezione se non vengono restituiti risultati?

    var result = List.Where(x => x == "foo").First();
    
  • E quando vorresti usare .FirstOrDefault ? Quando vuoi sempre il tipo predefinito se nessun risultato?

    var result = List.Where(x => x == "foo").FirstOrDefault();
    
  • E del resto, per quanto riguarda Take?

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

Ho trovato un sito Web che si avvicina per spiegare la necessità di FirstOrDefault
http://thepursuitofalife.com/the-linq-firstordefault-method-and-null-resultsets/
Se non ci sono risultati in una query e si desidera chiamare First () o Single () per ottenere una singola riga ... Si otterrà un'eccezione "Sequence contains no elements".

Disclaimer: Non ho mai usato LINQ, quindi mi scuso se questo è lontano dal marchio.



Un'altra differenza da notare è che se esegui il debug di un'applicazione in un ambiente di produzione potresti non avere accesso ai numeri di riga, quindi identificare quale particolare .First() in un metodo ha .First() l'eccezione potrebbe essere difficile.

Il messaggio di eccezione non includerà anche le espressioni Lambda che potresti aver utilizzato, il che renderebbe qualsiasi problema anche più difficile da eseguire il debug.

Ecco perché utilizzo sempre FirstOrDefault() anche se so che una voce nulla costituirebbe una situazione eccezionale.

var customer = context.Customers.FirstOrDefault(i => i.Id == customerId);
if (customer == null)
{
   throw new Exception(string.Format("Can't find customer {0}.", customerId));
}

Primo()

Quando sai che il risultato contiene più di 1 elemento previsto e dovresti solo il primo elemento della sequenza.

FirstOrDefault ()

FirstOrDefault () è come First () tranne che, se nessun elemento corrisponde alla condizione specificata, restituisce il valore predefinito del tipo sottostante della raccolta generica. Non getta InvalidOperationException se non è stato trovato alcun elemento. Ma la raccolta di un elemento o di una sequenza è nullo di quanto non faccia un'eccezione.


Vorrei usare First() quando so o mi aspetto che la sequenza abbia almeno un elemento. In altre parole, quando è un evento eccezionale che la sequenza è vuota.

Usa FirstOrDefault() quando sai che dovrai controllare se c'è un elemento o meno. In altre parole, quando è legale che la sequenza sia vuota. Non dovresti fare affidamento sulla gestione delle eccezioni per il controllo. (È una cattiva pratica e potrebbe danneggiare le prestazioni).

Infine, la differenza tra First() e Take() è che First() restituisce l'elemento stesso, mentre Take() restituisce una sequenza di elementi che contiene esattamente un elemento. (Se si passa 1 come parametro).


.First () genererà un'eccezione se non è presente alcuna riga da restituire, mentre .FirstOrDefault () restituirà il valore predefinito ( NULL per tutti i tipi di riferimento).

Quindi, se sei preparato e disposto a gestire una possibile eccezione, .First() va bene. Se si preferisce controllare comunque il valore restituito per! = Null, .FirstOrDefault() è la scelta migliore.

Ma immagino sia anche un po 'una preferenza personale. Usa quello che ha più senso per te e si adatta meglio al tuo stile di codifica.


Primo:

  • Restituisce il primo elemento di una sequenza
  • Genera eccezione: non ci sono elementi nel risultato
  • Usa quando: Quando è previsto più di 1 elemento e vuoi solo il primo

FirstOrDefault:

  • Restituisce il primo elemento di una sequenza o un valore predefinito se non viene trovato alcun elemento
  • Genera eccezione: solo se la fonte è nullo
  • Usa quando: Quando è previsto più di 1 elemento e vuoi solo il primo. Inoltre va bene che il risultato sia vuoto

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


Questo tipo di funzione appartiene agli operatori di elementi. Alcuni operatori di elementi utili sono definiti di seguito.

  1. In primo luogo / FirstOrDefault
  2. Ultima / LastOrDefault
  3. Singolo / SingleOrDefault

Utilizziamo gli operatori di elementi quando è necessario selezionare un singolo elemento da una sequenza in base a una determinata condizione. Ecco un esempio.

  List<int> items = new List<int>() { 8, 5, 2, 4, 2, 6, 9, 2, 10 };

L'operatore first () restituisce il primo elemento di una sequenza dopo aver soddisfatto la condizione. Se non viene trovato alcun elemento, verrà generata un'eccezione.

int result = items.Where (item => item == 2) .First ();

L'operatore FirstOrDefault () restituisce il primo elemento di una sequenza dopo aver soddisfatto la condizione. Se non viene trovato alcun elemento, restituirà il valore predefinito di quel tipo.

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


someList.First(); // exception if collection is empty.
someList.FirstOrDefault(); // first item or default(Type)

Quale usare? Dovrebbe essere deciso dalla logica aziendale, e non dalla paura dell'eccezione / fallimento del programma.

Ad esempio, se la logica aziendale dice che non possiamo avere zero transazioni in qualsiasi giorno lavorativo (supponiamo solo). Quindi non dovresti provare a gestire questo scenario con una programmazione intelligente. Userò sempre First () su tale raccolta e il programma fallirà se qualcos'altro ha rovinato la logica aziendale.

Codice:

var transactionsOnWorkingDay = GetTransactionOnLatestWorkingDay();
var justNeedOneToProcess = transactionsOnWorkingDay.First(): //Not FirstOrDefault()

Mi piacerebbe vedere altri commenti su questo.


.First genererà un'eccezione quando non ci sono risultati. .FirstOrDefault no, restituirà semplicemente null (tipi di riferimento) o il valore predefinito del tipo di valore. (ad esempio, come 0 per un int.) La domanda qui non è quando si desidera il tipo predefinito, ma più: siete disposti a gestire un'eccezione o gestire un valore predefinito? Poiché le eccezioni dovrebbero essere eccezionali, FirstOrDefault è preferito quando non si è sicuri se si otterranno risultati dalla query. Quando logicamente i dati dovrebbero essere lì, può essere presa in considerazione la gestione delle eccezioni.

Skip() e Take() vengono normalmente utilizzati durante l'impostazione del paging nei risultati. (Come mostrare i primi 10 risultati e il 10 successivo nella pagina successiva, ecc.)

Spero che questo ti aiuti.


Primo()

  1. Restituisce il primo elemento di una sequenza.
  2. Segnala un errore quando non ci sono elementi nel risultato o la fonte è nulla.
  3. dovresti usarlo, se è previsto più di un elemento e vuoi solo il primo elemento.

FirstOrDefault ()

  1. Restituisce il primo elemento di una sequenza o un valore predefinito se non viene trovato alcun elemento.
  2. Genera un errore Solo se la fonte è nullo.
  3. dovresti usarlo, se è previsto più di un elemento e vuoi solo il primo elemento. Buono anche se il risultato è vuoto.

Abbiamo una tabella UserInfos, che ha alcuni record come mostrato di seguito. Sulla base di questa tabella di seguito ho creato un esempio ...

Come usare First ()

var result = dc.UserInfos.First(x => x.ID == 1);

C'è solo un record in cui ID == 1. dovrebbe restituire questo record
ID: 1 Nome: Manish Cognome: Dubey Email: [email protected]

var result = dc.UserInfos.First(x => x.FName == "Rahul");   

Esistono più record in cui FName == "Rahul". Il primo record dovrebbe essere restituito.
ID: 7 Nome: Rahul Cognome: Sharma Email: [email protected]

var result = dc.UserInfos.First(x => x.ID ==13);

Non c'è nessun record con ID == 13. Dovrebbe verificarsi un errore.
InvalidOperationException: la sequenza non contiene elementi

Come utilizzare FirstOrDefault ()

var result = dc.UserInfos.FirstOrDefault(x => x.ID == 1);

C'è solo un record in cui ID == 1. dovrebbe restituire questo record
ID: 1 Nome: Manish Cognome: Dubey Email: [email protected]

var result = dc.UserInfos.FirstOrDefault(x => x.FName == "Rahul");

Esistono più record in cui FName == "Rahul". Il primo record dovrebbe essere restituito.
ID: 7 Nome: Rahul Cognome: Sharma Email: [email protected]

var result = dc.UserInfos.FirstOrDefault(x => x.ID ==13);

Non esiste alcun record con ID == 13. Il valore restituito è nullo

Spero che ti aiuterà a capire quando usare First() o FirstOrDefault() .


Ho trovato la risposta. Posso usare il metodo di estensione .AsQueryable<>() per convertire la mia lista in IQueryable, quindi eseguire l'ordine dinamico con esso.





c# .net linq