web-dev-qa-db-fra.com

Meilleures pratiques en matière de connexions de données C #?

Ok, c'est donc l'un de ces types de sujets d'opinion, mais en fonction de vos connaissances, de votre opinion et de votre pratique actuelle, quelle est la meilleure façon de mettre en place le scénario suivant?

Je suis en train de créer une application de saisie de données complète, et par vaste je veux dire que je n'ai que la configuration de base qui incorpore environ 15-25% du programme global et j'ai environ 15 formulaires qui sont partiellement configurés. (Ils ont encore besoin de travail) J'utilise SQL Compact 4.0 comme base de données backend, je n'ai pas vraiment besoin d'une base de données plus étendue car je ne stocke pas la valeur d'un MMO de données, et pour le moment ce n'est qu'une application locale .

Je serais ravi de pouvoir le configurer pour qu'il s'affiche comme une seule fenêtre qui se transforme simplement en différentes pages basées sur un système de menus, mais je n'arrive pas à trouver un bon tutoriel sur la façon dont cela serait accompli, donc si quiconque en connaît, veuillez m'éclairer.

Cependant, le scénario en question est de savoir comment se connecter aux bases de données. J'utilise 2 bases de données SQLCE, une qui stocke des données constantes basées sur les services et le personnel, et une seconde qui stocke les données en constante évolution ou les nouvelles données entrées en fonction de la première base de données. J'ai vu de nombreuses méthodes différentes sur la façon de configurer cela et actuellement j'en utilise une dans laquelle j'ai un BaseForm dont toutes les autres formes héritent. Dans le BaseForm, j'ai des méthodes et des variables qui sont communes à de nombreuses formes, minimisant ainsi la quantité de code qui est répétée.

Cela inclut les chaînes de connexion aux deux bases de données et 2 méthodes qui ouvrent une connexion à l'une d'entre elles. Ainsi:

internal SqlCeConnection dataConn = new SqlCeConnection(@"Data Source = |DataDirectory|\opi_data.sdf");
internal SqlCeConnection logConn = new SqlCeConnection(@"Data Source = |DataDirectory|\opi_logs.sdf");
internal SqlCeCommand command;

internal void openDataConnection() // Opens a connection to the data tables 
        {
            try
            {
                if(dataConn.State == ConnectionState.Closed)
                    dataConn.Open();
            }
            catch(SqlCeException ex)
            {
                MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        internal void openLogConnection() // Opens a connection to the log tables
        {
            try
            {
                if(logConn.State == ConnectionState.Closed)
                    logConn.Open();
            }
            catch (SqlCeException ex)
            {
                MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

Ensuite, chaque fois que j'ai besoin d'une connexion ouverte, j'appelle simplement la méthode de connexion ouverte qui correspond à la base de données à laquelle j'ai besoin d'accéder, puis je la ferme dans une instruction finally. De cette façon, une connexion n'est jamais ouverte très longtemps, juste au moment où elle est nécessaire. Bien sûr, cela signifie qu'il y a beaucoup d'appels aux méthodes de connexion ouvertes. Est-ce donc la meilleure façon de mettre en œuvre ce type de scénario, ou existe-t-il de meilleures façons?

Est-il préférable d'ouvrir simplement une connexion dès qu'un formulaire se charge, puis de la fermer à la fermeture du formulaire? J'ai des cas où plusieurs formulaires sont ouverts à la fois et chacun aurait probablement besoin d'une connexion ouverte aux bases de données, donc si l'un le ferme, les autres seront vissés non? Ou dois-je ouvrir une connexion aux deux bases de données au lancement de l'application? Toute contribution serait appréciée. Merci.

22
Josh C.

Les connexions sont regroupées par .NET, donc les recréer n'est généralement pas une opération coûteuse. Cependant, le fait de laisser les connexions ouvertes pendant de longues périodes peut entraîner des problèmes.

La plupart des "meilleures pratiques" nous disent d'ouvrir les connexions le plus tard possible (juste avant d'exécuter un SQL) et de les fermer dès que possible (juste après l'extraction du dernier bit de données).

Un moyen efficace de le faire automatiquement est d'utiliser les instructions using:

using (SqlConnection conn = new SqlConnection(...))
{
    using(SqlCommand cmd = new SqlCommand(..., conn))
    {
        conn.Open();
        using(DataReader dr = cmd.ExecuteReader())  // or load a DataTable, ExecuteScalar, etc.    
        {
             ...
        {
    }
}

De cette façon, les ressources sont fermées et éliminées même si une exception est levée.

En bref, ouvrir une connexion lorsque l'application s'ouvre ou lorsque chaque formulaire s'ouvre n'est probablement pas la meilleure approche.

68
D Stanley