Ma question porte sur l'état de connexion SQL, charge, etc., selon le code suivant:Y a-t-il des pièges à l'utilisation d'un type de retour IEnumerable <T> pour les données 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;
}
je peux voir ce qui est peut-être un problème s'il y a beaucoup de processus en cours d'exécution du code similaire lorsque les temps d'exécution entre les itérations de l'objet IEnumerable, car les connexions seront ouvertes plus longtemps, etc. Cependant, il semble également plausible que cela réduise l'utilisation du processeur sur le serveur SQL car il ne renvoie des données que lorsque l'objet IEnumerable est utilisé. Cela réduit également l'utilisation de la mémoire sur le client car le client doit seulement charger une instance de MyType pendant qu'il fonctionne plutôt que de charger toutes les occurrences de MyType (en itérant tout le DataReader et en retournant une liste ou quelque chose).
Y a-t-il des cas, vous pouvez penser où vous ne voudriez pas utiliser IEnumerable de cette manière, ou tout cas, vous pensez qu'il correspond parfaitement?
Quel type de charge cela met-il sur le serveur SQL?
Est-ce quelque chose que vous utiliseriez dans votre propre code (sauf mention de NHibernate, Subsonic, etc.)?
-
C'est un bon point, ne l'avait pas considéré non plus. Je suis tellement aveuglé par la façon dont je l'utiliserais! – scottm
@Guffa: L'utilisation de méthodes d'extension telles que 'Take' ne poserait pas de problème: La méthode' GetMyTypeObjects' n'est que du sucre syntaxique qui crée un objet itérateur 'IDisposable'. 'Take' appellera la méthode' Dispose' de l'itérateur quand elle aura fini, et donc disposera de la connexion, de la commande, du lecteur etc. – LukeH
@Guffa: Et il en va de même pour toutes les autres lectures partielles du résultat: Tant que vous appelez 'Dispose' lorsque vous avez terminé (ou préférez simplement tout emballer dans un bloc' using '), puis la connexion, la commande, le lecteur, etc. seront également éliminés. – LukeH