Essayer de comprendre le comportement erratique de DB Connection utilisé par Dapper

dapper micro-orm orm sqlconnection sql-server

Question

J'ai besoin d'aide pour mieux comprendre comment Dapper gère les connexions de base de données, et pourquoi DB Connection n'est pas correctement éliminé. J'ai codé autour des différents cas possibles. Dans mon code, je vérifie si la connexion est nulle et crée une nouvelle connexion en conséquence. Sur les demandes en cours, je constate que parfois la connexion est laissée ouverte, et d'autres fois, je trouve que la chaîne de connexion est manquante dans l'objet (le rendant inutilisable, mais ne le définissant pas à NULL). Je traite ces cas en conséquence, mais je voudrais comprendre pourquoi la connexion a ces états variables et n'est pas supprimée même si le code client implémente expressément une instruction using pour envelopper le code. Est-ce la gestion des connexions par ADO.net, y a-t-il un effet secondaire de Dapper ou juste des problèmes avec mon code?

Code de gestion des connexions

public class DatabaseContext : IDatabaseContext 
{
    private readonly string _connectionString;

    private DbConnection _connection;


    public DatabaseContext(string connectionString)
    {
        _connectionString = connectionString;

    }

    public IDbConnection Connection
    {
        get
        {

            if (_connection == null)
                _connection = new SqlConnection(_connectionString);

            if (string.IsNullOrEmpty(_connection.ConnectionString))
                _connection.ConnectionString = _connectionString;

            if (_connection.State != ConnectionState.Open)
                _connection.Open();

            return _connection;
        }
    }
}

Code client

public IEnumerable<PostSearResults> Search(SearchPostsBy searchPostsBy)
{
    DynamicParameters param;
    var sql = GetSearchSql(searchPostsBy,out param);//Gets SQL 

    using (var connection = _databaseContext.Connection)
    {
        var posts = connection.Query<PostSearResults>(sql, param);
        return posts.ToList();
    }
}

Réponse populaire

J'utilise également Dapper dans une application Web et j'implémente un DapperContext similaire au vôtre, mais j'implémente l'IDispose sur la classe comme suit:

    #region IDisposable

    private bool disposed = false;

    protected virtual void Dispose(bool disposing)
    {
        if (!this.disposed)
        {
            if (disposing)
            {
                if (transaction != null)
                { transaction.Dispose(); }
                if (cn != null)
                { cn.Dispose(); }
            }
        }
        this.disposed = true;
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    #endregion

Ma version de Dapper est celle qui ouvre une connexion si elle est fermée lorsque nous effectuons un appel, elle se ferme ensuite après l'exécution de la requête, si la connexion est ouverte lorsque l'appel effectue simplement exécuter la requête et laisser la connexion ouverte.

J'utilise également DI, donc ma durée de vie DapperContext est gérée par le conteneur DI. Il est donc supprimé lorsque le contexte de la requête Web est terminé et détruit. Mon référentiel Dapper se présente comme suit, avec un exemple de méthode GetPE

private readonly IDbConnection context;
private readonly DapperContext dapperContext;

public SFRepository(DapperContext dbContext)
{
    dapperContext = dbContext;
    context = dbContext.Connection;
}

public PEData GetPE(int peID)
{
     PEData rec = context.Query<PEData>("SELECT * FROM PEDATA WHERE ID= @ID", new { ID = peID }).FirstOrDefault();

     return rec;
}

Il a été très stable et je n'ai aucun comportement étrange.



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