S'assurer que la connexion à la base de données s'ouvre et se ferme chaque fois que j'utilise Dapper pour accéder à la base de données

c# dapper database-connection sql sql-server

Question

Voici ce que je fais actuellement dans l'une de mes classes de référentiel:

private IDbConnection db = new SqlConnection(ConfigurationManager.ConnectionStrings["MyConnString"].ConnectionString);

public IEnumerable<Product> GetProducts(int categoryId = null, bool? active = null)
{
    StringBuilder sql = new StringBuilder();
    sql.AppendLine("SELECT * ");
    sql.AppendLine("FROM Product ");
    sql.AppendLine("WHERE @CategoryId IS NULL OR CategoryId = @CategoryId ");
    sql.AppendLine("  AND @Active IS NULL OR Active = @Active");

    return this.db.Query<Product>(sql.ToString(), new { CategoryId = categoryId, Active = active }).ToList();
}

Une chose que je veux faire est de placer la propriété IDbConnection dans un BaseRepository dont tous mes autres repos héritent. Que dois-je faire pour que ma connexion à la base de données s'ouvre et se ferme correctement dans chacune de mes fonctions d'accès aux données, comme dans l'exemple ci-dessus? Voici ce que je fais actuellement avec Entity Framework (avec une déclaration d'utilisation de chaque fonction, mais maintenant je change de DAL pour utiliser Dapper:

using (var context = new MyAppContext())
{
    var objList = (from p in context.Products
                   where (categoryId == null || p.CategoryId == categoryId) &&
                         (active == null || p.Active == active)
                   select p).ToList();

    return objList;
}

J'ai remarqué dans les exemples de Dapper que tout est enveloppé dans un énoncé d'utilisation, comme prévu, mais je les vois parfois en train d'utiliser leurs fonctions dans la suite en utilisant:

using (var connection = Program.GetClosedConnection())

GetClosedConnection () renvoie un nouveau SqlConnection, mais quelle est la différence entre les deux?

public static SqlConnection GetOpenConnection(bool mars = false)
{
    var cs = connectionString;
    if (mars)
    {
        SqlConnectionStringBuilder scsb = new SqlConnectionStringBuilder(cs);
        scsb.MultipleActiveResultSets = true;
        cs = scsb.ConnectionString;
    }
    var connection = new SqlConnection(cs);
    connection.Open();
    return connection;
}
public static SqlConnection GetClosedConnection()
{
    return new SqlConnection(connectionString);
}

Réponse acceptée

Voici comment j'ai toujours fait ça:

SqlConnection dbConnection;
using (dbConnection = new SqlConnection(connectionString))
{
    /* 
       Whatever Dapper stuff you want to do. Dapper will open the
       connection and the using will tear it down.
    */
}

En ce qui concerne la deuxième partie de votre question, GetClosedConnection instancie simplement un objet SqlConnection , tandis que GetOpenConnection instancie et ouvre un objet SqlConnection . Vous (ou Dapper) devrez appeler manuellement Open() sur l'objet renvoyé par GetClosedConnection .


Réponse populaire

Cette réponse sera basée sur votre souhait "d'éviter la repitition".

Créez une classe d'extension de Dapper et mettez-y des fonctions et utilisez-la à la place. Ainsi:

    public IEnumerable<T> Query<T>(string sqlQuery, object parameters = null)
    {
        this.activeConnection.Open();

        var result = this.activeConnection
            .Query<T>(sqlQuery, parameters);

        this.activeConnection.Close();

        return result;
    }

Et en haut de la classe mettre un

    public SqlConnection activeConnection { get; private set; }

Qui est toujours défini dans le constructeur de la classe.



Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi
Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi