Je me pose des questions sur l'état de la connexion et de l'impact sur les performances du code par "rendement" lors de l'itération sur les données objet de lecteur
Voici mon exemple de code que j'utilise pour récupérer des données de la base de données:
sur la couche DAO:
public IEnumerable<IDataRecord> GetDATA(ICommonSearchCriteriaDto commonSearchCriteriaDto)
{
using(DbContext)
{
DbDataReader reader = DbContext.GetReader("ABC_PACKAGE.GET_DATA", oracleParams.ToArray(), CommandType.StoredProcedure);
while (reader.Read())
{
yield return reader;
}
}
}
Sur BO couche, je suis l'appel de la méthode ci-dessus comme:
List<IGridDataDto> GridDataDtos = MapMultiple(_costDriversGraphDao.GetGraphData(commonSearchCriteriaDto)).ToList();
sur mappeur couche MapMultiple méthode est définie comme:
public IGridDataDto MapSingle(IDataRecord dataRecord)
{
return new GridDataDto
{
Code = Convert.ToString(dataRecord["Code"]),
Name = Convert.ToString(dataRecord["Name"]),
Type = Convert.ToString(dataRecord["Type"])
};
}
public IEnumerable<IGridDataDto> MapMultiple(IEnumerable<IDataRecord> dataRecords)
{
return dataRecords.Select(MapSingle);
}
Le code ci-dessus fonctionne bien, mais je me pose des questions sur deux préoccupations avec le code ci-dessus.
- Combien de temps les données du lecteur de connexion sera ouvert?
- Quand je considère le code de facteur de performance seulement, Est-ce une bonne idée d'utiliser les "taux de retour" au lieu d'ajout d'enregistrement dans une liste et le retour de l'ensemble de la liste?
OriginalL'auteur Sanjeev Rai | 2013-03-13
Vous devez vous connecter pour publier un commentaire.
.ToList()
, donc ça va être bien. Dans le cas plus général, oui: le lecteur sera ouverte pour la quantité de temps que vous prenez à le parcourir; si vous faites un.ToList()
qui sera minime; si vous faites unforeach
et (pour chaque élément) externe de la requête http et attendre 20 secondes, alors oui il sera ouvert plus longtemps.Si vous retourne un itérateur bloc, l'appelant peut décider de ce qui est sain d'esprit; si vous retournez toujours une liste, ils n'ont pas beaucoup d'option. Un troisième moyen (ce que nous faisons dans dapper) est de faire le choix le leur; nous avons une option de
bool
paramètre dont la valeur par défaut de "retourner une liste", mais dont l'appelant peut changer pour indiquer "retour d'un itérateur bloc"; en gros:dans les paramètres, et:
dans la mise en œuvre. Dans la plupart des cas, le retour d'une liste est parfaitement raisonnable et évite beaucoup de problèmes, c'est pourquoi nous faire défaut.
OriginalL'auteur Marc Gravell
La connexion reste ouverte jusqu'à ce que le
reader
est rejetée, ce qui signifie qu'il serait ouvert jusqu'à l'itération est terminée.Cela dépend de plusieurs facteurs:
yield return
vous aidera à économiser sur la quantité de données transférées sur le réseauyield return
vous aidera à enregistrer sur la mémoire utilisée lors de l'utilisation de pointe point de votre programmeyield return
. Si l'itération va durer une quantité importante de temps sur plusieurs threads simultanés, le nombre de curseurs ouverts sur le SGBDR côté peut devenir dépassés.OriginalL'auteur dasblinkenlight
Cette réponse ignore les défauts dans la mise en œuvre et couvre l'idée générale.
Il est nécessaire de trouver un compromis - il est impossible de dire si c'est une bonne idée, sans en connaître les contraintes de votre système - qu'est-ce que la quantité de données que vous prévoyez d'obtenir, de la consommation de mémoire vous sont disposés à accepter la charge prévue sur la base de données, etc
OriginalL'auteur Zdeslav Vojkovic