Попытка понять нестабильное поведение подключения к БД, используемого Dapper

Мне нужна помощь, чтобы лучше понять, как Dapper обрабатывает соединения с БД и почему соединение с БД не удаляется должным образом. Я закодировал различные возможные случаи. В моем коде я проверяю, имеет ли _connection значение null, и соответственно создаю новое соединение. Выполняя запросы, я обнаружил, что иногда соединение остается открытым, а в других случаях я обнаруживаю, что строка подключения отсутствует в объекте (что делает его непригодным для использования, но не устанавливает для него значение NULL). Я обрабатываю эти случаи соответствующим образом, но хотел бы понять, почему соединение имеет эти различные состояния и не удаляется, даже если клиентский код явно реализует оператор using для обертывания кода. Это обработка соединений ADO.net, есть ли побочный эффект Dapper или просто проблемы с моим кодом?

Код управления подключением

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;
        }
    }
}

Код клиента

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();
    }
}

person Yogiraj    schedule 29.04.2014    source источник
comment
Так вы не знаете, зачем пишете этот код ?! Зачем ты тогда это написал? Кстати, обзор кода не по теме, вы должны разместить свой вопрос на codereview.stackexchange.com   -  person MikeSW    schedule 04.05.2014
comment
@MikeSW Я хочу знать, почему DBConnection не удаляется должным образом, даже если клиентский код обертывает его в операторе using. Что-то держится за это. Это обработка соединений ADO.net, есть ли побочный эффект Dapper или просто проблемы с моим кодом? Может ли это быть просто обзорный вопрос с этими тремя возможностями? Зачем комментировать меня (не по теме), чем вопрос?   -  person Yogiraj    schedule 05.05.2014
comment
Вы должны были спросить об этом вместо того, чтобы писать объяснение того, что делает код. Если вы хотите повторно использовать соединение, вам следует закрыть его, а НЕ удалять. Удаление сбрасывает SqlConnection, и он выбрасывает `` объект уже удален '' или что-то подобное   -  person MikeSW    schedule 05.05.2014
comment
Обновлено. Спасибо за вклад. Использование также закрывает соединение (stackoverflow.com/questions/4389506/), что является целью этого конкретного запроса. Для запросов (инициированная пользователем веб-операция), которые следуют за упомянутым в вопросе, я обнаружил, что объект DBConnection все еще работает и открыт, не говоря уже о удалении. Почему это происходит? Я также попытался явно реализовать метод удаления, реализовав интерфейс IDisposable. У меня все еще та же проблема.   -  person Yogiraj    schedule 05.05.2014


Ответы (1)


Я также использую Dapper в веб-приложении и реализую DapperContext, аналогичный вашему, но я реализую IDispose в классе следующим образом:

    #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

Моя версия Dapper - это та, которая открывает соединение, если оно закрывается, когда мы делаем вызов, а затем закрывается после выполнения запроса, если соединение открывается, когда я вызываю Dapper, просто выполняет запрос и оставляет соединение открытым.

Я также использую DI, поэтому мое время жизни DapperContext управляется контейнером DI, поэтому он удаляется, когда контекст веб-запроса завершается и уничтожается. Мой репозиторий Dapper выглядит следующим образом, с примером метода 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;
}

Он был очень стабильным, и у меня нет странного поведения.

person Gboyega Sulaiman    schedule 10.06.2015