La mia domanda riguarda lo stato di connessione SQL, carico, ecc in base al codice seguente:Ci sono dei problemi nell'utilizzo di un tipo di restituzione IEnumerable <T> per dati SQL?
public IEnumberable<MyType> GetMyTypeObjects()
{
string cmdTxt = "select * from MyObjectTable";
using(SqlConnection conn = new SqlConnection(connString))
{
using(SqlCommand cmd = new SqlCommand(cmdTxt, conn))
{
conn.Open();
using(SqlDataReader reader = cmd.ExecuteReader())
{
while(reader.Read())
{
yield return Mapper.MapTo<MyType>(reader);
}
}
}
}
yield break;
}
posso vedere questo forse essere un problema se ci sono molti processi in esecuzione codice simile con tempi di esecuzione lunghi tra le iterazioni di l'oggetto IEnumerable, poiché le connessioni saranno aperte più a lungo, ecc. Tuttavia, sembra anche plausibile che ciò ridurrà l'utilizzo della CPU sul server SQL perché restituisce solo i dati quando viene utilizzato l'oggetto IEnumerable. Riduce anche l'utilizzo della memoria sul client perché il client deve solo caricare un'istanza di MyType mentre funziona piuttosto che caricare tutte le occorrenze di MyType (eseguendo un iter attraverso l'intero DataReader e restituendo un elenco o qualcosa del genere).
Esistono casi si può pensare di dove non si vuole utilizzare IEnumerable in questo modo, o tutte le istanze si pensa che si adatta perfettamente?
Che tipo di carico inserisce sul server SQL?
È questo qualcosa che si utilizzerà nel proprio codice (salvo eventuali menzioni di NHibernate, Subsonic, ecc.)?
-
Questo è un buon punto, non l'avevo nemmeno considerato. Sono così accecato dal modo in cui lo userei! – scottm
@Guffa: l'utilizzo di metodi di estensione come 'Take' non sarebbe un problema: il metodo' GetMyTypeObjects' è solo zucchero sintattico che crea un oggetto iteratore 'IDisposable'. 'Take' chiamerà il metodo 'Dispose' dell'iteratore una volta terminato, e quindi eliminerà la connessione, il comando, il lettore ecc. – LukeH
@Guffa: E lo stesso vale per qualsiasi altra lettura parziale del set di risultati: finché tu chiama 'Dispose' quando hai finito (o preferibilmente avvolgi tutto in un blocco' using') poi la connessione, il comando, il lettore etc saranno anch'essi eliminati. – LukeH