Программа к представлению Shared Memory in Windows?

Соединение закрывается только при удалении экземпляра класса DataBase. Однако, хотя этот класс реализует одноразовый шаблон, он не реализует интерфейс IDisposable - поэтому вы не можете использовать его в выражении using.
Более того, вы должны полагаться на тех, кто использует этот класс, чтобы распоряжаться им.
Если они этого не сделают, соединение не будет закрыто, пока не будет вызван финализатор, и это полностью вне контроля разработчика. Он может даже не вызываться вообще - сборщику мусора может не потребоваться очистка памяти во время выполнения того приложения, которое использует этот код.

Вот почему правильный способ обработки соединений с базой данных - это локальная переменная внутри оператора using.

То, что вы хотите сделать, это создать соединение и открыть его как можно позже, и утилизировать его как можно скорее.
Правильный метод для обработки вызовов к базе данных выглядит следующим образом:

int ExecuteNonQuery(string sql)
{
    using(var con = new SqlConnection(connectionString))
    {
        using(var cmd = new SqlCommand(sql, con))
        {
            con.Open();
            return cmd.ExecueNonQuery();
        }
    }
}

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

У меня есть проект на GitHub под названием ADONETHelper (которым я пренебрегал в течение последнего года или около того из-за нехватки свободного времени), который был написан для уменьшения повторения кода при использовании ADO .Net напрямую.
Я написал это несколько лет назад, поэтому, конечно, теперь я имею в виду улучшения, но, как я уже сказал, у меня нет свободного времени, чтобы поработать над этим - но общая идея по-прежнему актуальна и полезна. По сути, у него есть единственный метод Execute, который выглядит следующим образом:

public T Execute(string sql, CommandType commandType, Func function, params IDbDataParameter[] parameters)
{
    using (var con = new TConnection())
    {
        con.ConnectionString = _ConnectionString;
        using (var cmd = new TCommand())
        {
            cmd.CommandText = sql;
            cmd.Connection = con;
            cmd.CommandType = commandType;
            if (parameters.Length > 0)
            {
                cmd.Parameters.AddRange(parameters);
            }
            con.Open();
            return function(cmd);
        }
    }
}

, чем я добавил несколько методов, которые используют этот метод:

public int ExecuteNonQuery(string sql, CommandType commandType, params IDbDataParameter[] parameters)
{
    return Execute(sql, commandType, c => c.ExecuteNonQuery(), parameters);
}

public bool ExecuteReader(string sql, CommandType commandType, Func populate, params IDbDataParameter[] parameters)
{
    return Execute(sql, commandType, c => populate(c.ExecuteReader()), parameters);
}

и так далее.

Не стесняйтесь заимствовать идеи из этого проекта - или даже использовать их как есть - у меня есть несколько приложений, использующих это, и они работают очень хорошо в течение довольно долгого времени.

7
задан SamB 25 January 2011 в 23:58
поделиться