C'est tout. Quelques points supplémentaires à considérer:
- Où obtenez-vous votre chaîne de connexion? Vous ne voulez pas que cela soit codé de toutes pièces et vous devrez peut-être le sécuriser.
- Vous avez souvent d'autres objets pour créer aussi bien avant vraiment utiliser la connexion (
SqlCommand
, SqlParameter
, DataSet
, SqlDataAdapter
), et vous voulez attendre aussi longtemps que possible pour ouvrir la connexion. Le modèle complet doit en tenir compte.
- Vous voulez vous assurer que l'accès à votre base de données est forcé dans sa propre classe ou ensemble de couches de données. Donc, une chose courante à faire est d'exprimer cela comme un appel de fonction privée:
.
private static string connectionString = "load from encrypted config file";
private SqlConnection getConnection()
{
return new SqlConnection(connectionString);
}
Et puis rédigez votre échantillon comme ceci:
using (SqlConnection sqlConn = getConnection())
{
// create command and add parameters
// open the connection
sqlConn.Open();
// run the command
}
Cet échantillon ne peut exister que dans votre classe d'accès aux données. Une alternative consiste à marquer internal
et à répartir la couche de données sur un ensemble complet. La chose principale est qu'une séparation propre de votre code de base de données est strictement appliquée.
Une véritable mise en œuvre pourrait ressembler à ceci:
public IEnumerable<IDataRecord> GetSomeData(string filter)
{
string sql = "SELECT * FROM [SomeTable] WHERE [SomeColumn] LIKE @Filter + '%'";
using (SqlConnection cn = getConnection())
using (SqlCommand cmd = new SqlCommand(sql, cn))
{
cmd.Parameters.Add("@Filter", SqlDbType.NVarChar, 255).Value = filter;
cn.Open();
using (IDataReader rdr = cmd.ExecuteReader())
{
while (rdr.Read())
{
yield return (IDataRecord)rdr;
}
}
}
}
Notez que j'ai pu « pile » la création des objets cn
et cmd
, et réduire ainsi l'imbrication et seulement créer un bloc de portée. Enfin, un mot d'avertissement à propos de l'utilisation du code yield return
dans cet exemple spécifique. Si vous appelez la méthode et ne complétez pas votre DataBinding
ou toute autre utilisation tout de suite, il pourrait maintenir la connexion ouverte pendant une longue période. Un exemple de ceci est l'utiliser pour définir une source de données dans l'événement Load
d'une page ASP.NET. Étant donné que l'événement de liaison de données réel ne se produira pas plus tard, vous pouvez maintenir la connexion ouverte beaucoup plus longtemps que nécessaire.
point 1: Je stocke mes chaînes de connexion dans la section de l'app/web.config Point 2: Est-ce quelque chose dont je devrais m'inquiéter? Je fais normalement SqlConnection, puis je l'ouvre, puis je crée ma commande sqlCommand, puis je prends de là. Point 3: Nous faisons tous nos accès DB à partir d'une classe lib. Je n'aime pas faire l'accès DB forme l'application de base. Cela vaut-il la peine de créer la méthode getConnection? –
Neale
Étant donné que vous utilisez un accès à la bibliothèque lib pour tous les db, il est très simple de faire en sorte que la chaîne de connexion fasse partie du fichier .config de la classe lib plutôt que du fichier .config global de l'application. Cela devrait être assez bon pour imposer une séparation de couche de données propre, mais en même temps il n'y a aucune raison de rendre la méthode publique non plus. Cela devrait concerner les points 1 et 3. Pour le point 2, cela ne blesse probablement rien de l'ouvrir pour une ou deux lignes supplémentaires, mais cela n'aide pas non plus. Je suis en train d'éditer pour une autre raison, vous pourriez vouloir le faire de cette façon. –
Votre exemple de retour de rendement est légèrement trompeur. Une fonction construite autour de 'yield return' ne démarre pas executig avant le premier appel de' MoveNext() 'sur' IEnumerator'. Ainsi, même si vous appelez la fonction, la connexion ne sera pas ouverte tant que vous n'aurez pas recommencé à parcourir les résultats. –