Mi pregunta tiene que ver el estado de conexión de SQL, carga, etc. basado en el siguiente código:¿Hay algún inconveniente al utilizar un tipo de retorno IEnumerable <T> para datos 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;
}
puedo ver esta siendo posiblemente un problema si hay muchos procesos que se ejecutan código similar con largos tiempos de ejecución entre las iteraciones de el objeto IEnumerable, porque las conexiones estarán abiertas durante más tiempo, etc. Sin embargo, también parece plausible que esto reduzca el uso de CPU en el servidor SQL porque solo devuelve datos cuando se utiliza el objeto IEnumerable. También reduce el uso de memoria en el cliente porque el cliente solo tiene que cargar una instancia de MyType mientras funciona en lugar de cargar todas las apariciones de MyType (iterando a través de todo el DataReader y devolviendo una lista o algo así).
¿Hay casos en que se pueda imaginar en el que no se desea utilizar IEnumerable de este modo, o cualquier instancia que creo que encaja perfectamente?
¿Qué tipo de carga no someten quizás en el servidor SQL?
¿Es esto algo que usaría en su propio código (salvo mención alguna de NHibernate, subsónico, etc)?
-
Ese es un buen punto, tampoco lo había considerado. ¡Estoy tan cegado por la forma en que lo usaría! – scottm
@Guffa: Usar métodos de extensión como 'Take' no sería un problema: el método' GetMyTypeObjects' es simplemente azúcar sintáctico que crea un objeto iterador 'IDisposable'. 'Take' llamará al método' Dispose' del iterador cuando esté listo, y que luego eliminará la conexión, el comando, el lector, etc. – LukeH
@Guffa: Y lo mismo se aplica a cualquier otra lectura parcial del conjunto de resultados: siempre y cuando usted llame a 'Dispose' cuando haya terminado (o preferiblemente solo envuelva todo en un bloque 'using'), luego la conexión, el comando, el lector, etc. también serán eliminados. – LukeH