Каков правильный шаблон для закрытия OdbcConnection на веб-странице asp.net-mvc - PullRequest
1 голос
/ 21 ноября 2011

У меня есть веб-сайт, и у меня есть класс доступа к данным, который имеет OdbcConnection.В конструкторе у меня есть этот код:

    public MySybaseProvider()
    {
        _conn = GetConn();        
    }

    public OdbcConnection GetConn()
    {
        string connString = "DSN=SybaseIQ;Eng=SYSERVER;Links=tcpip(Host=" + _connectionInfo.Host + ";Port=" + _connectionInfo.Port + ");UID=" + _connectionInfo.User + ";PWD=" + _connectionInfo.Pwd + ";";

        return new OdbcConnection(connString);
    }

и во всем классе у меня есть следующий код:

    private OdbcQuery GetQuery(string sql)
    {
        return new OdbcQuery(_conn, sql);
    }

Я пытаюсь найти лучший способ убедиться, что яправильно закройте соединение.Должен ли я реализовать IDisposable?я должен открыть и закрыть соединение по каждому запросу?Есть ли здесь другие рекомендации?

РЕДАКТИРОВАТЬ:

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

Ответы [ 4 ]

1 голос
/ 21 ноября 2011

Итак, я отправил еще один ответ, потому что понял, что обычно я использую Enterprise Library для доступа к данным, а не чистый .net, который немного меняет ситуацию.Например, DataAccessApplicationBlock (DAAB) заботится об открытии и закрытии соединения (й) с базой данных, поэтому у меня его тоже нет, поэтому я использую его как ниже.Также в этом случае более простой и эффективный способ сделать то, что описано, состоит в том, чтобы выполнить все операторы SELECT в 1 сохраненном процессе, а затем прочитать и проанализировать каждый набор результатов по одному за раз.*

Сохраненный процесс

Create PROCEDURE [dbo].[GetUserByEmail]
    @UserID int,
    @AccountID int,
AS
BEGIN
    SET NOCOUNT OFF;

    SELECT * FROM Users WHERE UserID = @UserID and AccountID = @AccountID

    SELECT * FROM UserAddresses WHERE UserID = @UserID
END

C # Код:

public class DataAccessLayer
{
    private static DataAccessLayer me = new DataAccessLayer();

    private DataAccessLayer() { }

    public static DataAccessLayer GetInstance()
    {
        return me;
    }

    public Database GetDatabase(string connectionString, string provider)
    {
       DbProviderFactory providerFactory = DbProviderFactories.GetFactory(provider);

        return new GenericDatabase(connectionString,
                                   providerFactory);
    }
}

public class Repository
{
    protected Database curDatabase;

    public Repository()
    {
        curDatabase = DataAccessLayer.GetInstance().GetDatabase("ConnectionString", "System.Data.Odbc");
    }

    public Database CurrentDatabase
    {
        get { return curDatabase; }
    }
}

public class UserRepository : Repository
{
    public User GetUser(int urserID, int accountID)
    {
        using (IDataReader dataReader = CurrentDatabase.ExecuteReader("StroedProcName", urserID, accountID))
        {
            //User Details
            while (dataReader.Read())
            {
                //Parse Data
            }

            dataReader.NextResult();

            //User Address(es)
            while (dataReader.Read())
            {
                //Parse Data
            }
        }
    }
}
1 голос
/ 21 ноября 2011

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

using (var conn = new OdbcConnection(_connString)) {
  conn.Open();

  // do a database command ...
}

(Примечаниечто я изменил дизайн, чтобы сохранить _connString в поле)

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

0 голосов
/ 21 ноября 2011

Вы можете использовать следующую схему, чтобы убедиться, что соединение установлено. Даже если произойдет ошибка, она будет ликвидирована. Для более безопасного кодирования вы должны использовать компоновщик строки соединения для построения соединения. Создавать / использовать соединение следует только тогда, когда вы планируете выполнить операцию. Это не должно торчать в течение жизни вашего приложения. Вместо этого вы можете использовать строку подключения / свойства.

    public OdbcConnection GetConn()
    {
        OdbcConnectionStringBuilder sb = new OdbcConnectionStringBuilder();
        sb.Driver = "Microsoft Access Driver (*.mdb)";
        sb.Add("Dbq", "C:\\info.mdb");
        sb.Add("Uid", "Admin");
        sb.Add("Pwd", "pass!word1");
        OdbcConnection con = new OdbcConnection(sb.ConnectionString);
        return con;
    }


    public void DoSomeWork()
    {
        using(OdbcConnection connection = GetConn())
        {
            // Do stuff with your connection here


        }
    }
0 голосов
/ 21 ноября 2011

Я бы сказал, что вы обязательно должны реализовать IDisposable и следовать шаблону dispose Имейте в виду, что сборщик мусора ничего не знает о IDisposable.В качестве последнего средства вы должны иметь финализатор, который в случае необходимости прервет соединение с БД, но по возможности подавит финализатор (см. Ссылку, которую я добавил, для всех подробностей).

Относительно того, хотите ли вы создать новое соединение для каждой команды или оставить его на всю жизнь объекта, это гораздо более субъективно и зависит от вашего сценария, среды и многих других вещей.Я рекомендую изучить оба и посмотреть, что вы думаете.Если это «настоящая» БД, возможно, поговорите с БД и посмотрите, что они думают.

В любом случае, реализация IDisposable - ваш друг, так как вы можете иметь хороший, чистый, четко определенный код утилизации в шаблоне, с которым знакомы все разработчики .NET.

...