2012-02-17 19 views
5

Ho un metodo di fornitura in DAL:Record del database di restituzione del rendimento mediante LinqToSql?

public IEnumerable<RecordType> GetRecords() 
{ 
    using (LinqDataContext context = new LinqDataContext()) 
    { 
     var records = context.RecordTable; 

     foreach (RecordType record in records) 
     { 
      yield return record; 
     } 
    } 
} 

Il metodo dei consumatori utilizza i record in un ciclo foreach. In questo modo, desidero salvare l'utilizzo della memoria non memorizzando nella cache tutti i record da RecordTable, poiché LinqToSql utilizza un DataReader dietro la scena.

Ho due domande su questo scenario però:

  1. È vero che il rendimento-ritorno sopra consente di risparmiare risorse e funziona più velocemente di quanto la memorizzazione nella cache tutti i record ad un array (.ToArray())?

  2. Intende la connessione dati automaticamente chiusi correttamente (mi riferisco alla dichiarazione using) se si verifica un errore all'interno del foreach ciclo del metodo di consumare o se il metodo di consumo si romperà il ciclo foreach in mezzo (come trovato un record richiesto e break)?

risposta

3

Nel caso di esecuzione di una query di base, si può funziona in questo modo (certamente è possibile) - tuttavia, nel caso di interrogare uno Table<T> nudo, lo potrebbe essere essere che tutti i buffer prima; potresti forse provare a interrogare il conteggio durante l'iterazione o eseguire una traccia. In questo caso I sospetto verrà bufferizzato per primo.

Re chiuso: che dipende anche; p Se qualcuno sta usando foreach, allora sì: dal foreach dismette in modo esplicito l'iteratore tramite finally. Però! Non è garantito se qualcuno fa, per esempio (molto cattivo e permissive):

var iter = yourData.GetEnumerator(); 
if(iter.MoveNext()) { 
    Console.WriteLine(iter.Current.Name); // first record of, say, 20 
} 
// and don't dispose the iterator == bad 

poi dato l'iteratore non fa una: le disposta, b: esaurirsi, ec: non si arresta, esso non si spegne correttamente (nessuna di queste 3 condizioni corrisponderà a chiuderla correttamente). Enfasi: questo è un caso patologico: normalmente è ragionevolmente sicuro dire "si chiuderà, sì".

Se si desidera garantita non-buffering, notare che "dapper" ha che, se si imposta buffered-false:

IEnumerable<Customer> customers = connection.Query<Customer>(
     "select * from Customer", buffered: false); 

(si può anche gestire i parametri, ecc)

3

1) yield non sarà necessariamente più veloce per ottenere tutti i valori, ma permetterebbe il codice per avviare la gestione dei risultati prima che il database ha restituito tutti i risultati. Ovvero, yield restituisce il primo risultato nell'istante in cui viene visualizzato, mentre ToArray() deve attendere la visualizzazione di tutti i risultati prima di tornare. Naturalmente, se i provider sottostanti restituiscono tutti i risultati contemporaneamente a causa del buffering o di altri motivi, ciò potrebbe non fare la differenza.

2) Sì, using disporrà del LinqDataContext non importa come si esce dal blocco utilizzando (eccezioni/ritorno/pausa/...)

+1

In realtà, 2 è "fintanto che il chiamante si comporta correttamente" - non è strettamente come "garantito" come la maggior parte 'using' sono –

+0

@MarcGravell sto supponendo che si sta parlando non (correttamente) elencando l'Enumerable completo o mi manca qualcos'altro? –

+0

sì, spostando manualmente l'iteratore e eseguendolo in modo errato. Non è un problema quando si usa 'foreach', che useranno le persone più sensate. –

2
  1. Il l'iteratore verrà valutato pigramente. Tirerà il primo oggetto e poi lo "renderà" al suo consumatore.L'impatto sulle prestazioni dipenderà dal modo in cui viene implementato LinqDataContext (potrebbe memorizzare la cache internamente). L'utilizzo di ToArray() o ToList() imporrà tutti gli elementi fuori da LinqDataContext prima di procedere. Pertanto, l'utilizzo di ToArray() non produrrà nulla finché LinqDataContext non restituirà ogni elemento. Che sia ottimale o no, dipende da te.
  2. Sì, il "utilizzo" verrà applicato correttamente.
Problemi correlati