Где разместить общее соединение с базой данных для моих классов

11

У меня есть несколько классов (репозитории), которые выполняют задачу сохранения / извлечения некоторых объектов в / из базы данных; все они должны установить соединение с одной базой данных.

Я думал, чтобы избежать переопределения ConnectionStringи SqlConnectionв каждом классе, передавая им открытую связь. Тогда где / когда лучшее место / время, чтобы определить / открыть это соединение и передать его классам?

Есть ли лучшие подходы / шаблоны для доступа к этому общему ресурсу?

Ahmad
источник

Ответы:

10

Передача открытого соединения каждому классу, вероятно, не лучшая идея. Ознакомьтесь с разделом Создание соединений с базой данных - один раз или для каждого запроса?

Рекомендуется открывать и закрывать соединение для каждого запроса, который вы хотите выполнить, а не передавать открытое соединение в ваш репозиторий.

Вы можете попробовать что-то вроде этого, чтобы помочь вам управлять своими подключениями.

public class Repository
{
    private readonly string _connectionString;

    public Repository()
    {
        _connectionString = ConfigurationManager.ConnectionStrings["connString"].ConnectionString
    }

    protected SqlConnection GetConnection()
    {
         return new SqlConnection(_connectionString);
    }


}

public sealed class UserRespository : Repository
{

    public User GetUsers()
    {
        using (var connection = GetConnection())
        {
            using (var commnad = new SqlCommand("SqlQuery", connection))
            {
                //Execute Query
                //Return results
            }
        }
    }
}
Гибсон
источник
5

Наличие открытой связи и ее передача между классами, как правило, плохая идея. Конечно, открытие соединения - это серьезное снижение производительности, но об этом уже заботится пул соединений, повторно используя уже открытые соединения. Замечание: всегда ждите как можно дольше вызова connection.Open(), особенно в многопоточном коде, поскольку это назначит соединение вашему методу (который потенциально увеличит необходимое количество открытых соединений с базой данных).

Чтобы сделать ваши классы как можно более общими, я бы порекомендовал иметь базовый класс, представляющий метод с IDbConnection, и ваши репозитории будут иметь более общую реализацию.

internal abstract class Repository
{
    private static readonly string ConnectionString = ConfigurationManager.ConnectionStrings["myconnectionstring"].ConnectionString;

    protected IDbConnection GetConnection()
    {
        return new SqlConnection(ConnectionString);
    }
}

public class MyRepository : Repository
{
    public IEnumerable<object> Get()
    {
        using (var connection = GetConnection())
        {
            connection.Open();

            ...
        }
    } 
}
Ричард Янссон
источник