Убедитесь, что соединение БД SQL всегда закрыто после вызова каждой функции репо

Я пытаюсь выяснить, нужен ли мне оператор using в каждой из моих функций репозитория, чтобы убедиться, что соединение закрывается после каждого пакета вызовов базы данных.

Например: я хочу вызвать connection.query или connection.execute несколько раз внутри определенных функций репозитория. Если я не использую оператор использования, когда мое соединение когда-либо закроется? Цель состоит в том, чтобы сделать его максимально эффективным для веб-разработки.

BaseRepository

public static string ConnectionString => @"Server=.;Database=applicationDb;User ID=sa;Password=Password12!";
protected SqlConnection _connection;
protected SqlConnection connection => _connection ?? (_connection = GetOpenConnection());

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

public SqlConnection GetClosedConnection()
{
    var conn = new SqlConnection(ConnectionString);
    if (conn.State != ConnectionState.Closed) throw new InvalidOperationException("should be closed!");
    return conn;
}

public void Dispose()
{
    _connection?.Dispose();
}

CustomerRepository: BaseRepository

С настройкой BaseRepository так оно и есть. Есть ли разница между следующим:

public IEnumerable<Customer> GetCustomers()
{
    using (connection)
    {
        StringBuilder sql = new StringBuilder();
        sql.AppendLine("SELECT Id, Name, Email ");
        sql.AppendLine("FROM Customer;");

        StringBuilder deleteSql = new StringBuilder();
        deleteSql = new StringBuilder();
        deleteSql.AppendLine("DELETE FROM Xyz ");
        deleteSql.AppendLine("FROM CustomerId = @CustomerId;");
        connection.Execute(deleteSql.ToString(), new { CustomerId = 5 });

        return connection.Query<Customer>(sql.ToString()).ToList();
    }
}

ИЛИ без использования:

public IEnumerable<Customer> GetCustomers()
{
        StringBuilder sql = new StringBuilder();
        sql.AppendLine("SELECT Id, Name, Email ");
        sql.AppendLine("FROM Customer;");

        StringBuilder deleteSql = new StringBuilder();
        deleteSql = new StringBuilder();
        deleteSql.AppendLine("DELETE FROM Xyz ");
        deleteSql.AppendLine("FROM CustomerId = @CustomerId;");
        connection.Execute(deleteSql.ToString(), new { CustomerId = 5 });

        return connection.Query<Customer>(sql.ToString()).ToList();
}

2 ответа

Решение

Вы должны обернуть ваши звонки в using заявление (или try...catch если вы хотите обработать исключения), и он закроет его и утилизирует автоматически.

Мое предложение здесь заключается в использовании using заявление, потому что цель using Утверждение состоит в том, что когда управление достигнет конца использования, оно избавится от объекта использования блока и освободит память. его назначение не только для автоматического закрытия соединения, в основном он будет располагать объектом соединения и, очевидно, соединение также закрывается из-за этого.

Другие вопросы по тегам