2012-03-21 5 views
1

У меня есть клиентское серверное приложение, использующее .NET Remoting.
У меня есть вспомогательный класс на серверной части моего приложения DBQuery.
DBQuery содержит DatabaseConnection и объект SQLCommand, Commander и выполняет переданные ему запросы.В приложении .NET Remoting для приложения должен быть статический объект подключения к базе данных

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

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

текущие свойства, определяемые ниже:

/// <summary> connection used for querying with </summary> 
public DBConn DBConnection 
{ get { return _conn ?? (_conn = new DBConn()); } } 

/// <summary> Command object for processing the queries </summary> 
private SqlCommand Commander 
{ 
    get 
    { 
     return _commander ?? 
      (_commander = DBConnection.Connection.CreateCommand()); 
    } 
} 

DBConn - оборачивает SqlConnection и подает соответствующую информацию о соединении с app.config

ответ

1

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

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

Также, где вы располагаете соединением? Очень сложно избавиться от статического объекта, если вы не выполняете работу, чтобы подключиться к событию выключения, что не всегда надежно. Опираясь на закрытие AppDomain, чтобы распоряжаться вещами для вас, это не хорошая практика.

Создайте соединение, когда оно вам нужно, и удалите его, когда вы закончите с ним. На основе коды вы дали, в простых словах:

using(var conn = new DbConn().Connection) 
{ 
    SqlCommand command = conn.CreateCommand(); 
    /* query and get results here */ 
} 

Хотя на самом деле вы можете сделать вас DbConn класс IDisposable и цепь к Dispose методе основных Connection «ы в его реализации IDisposable.Dispose - это путь вы можете сделать

using(var dbconn = new DbConn()) 
{ 
    //now you can use dbconn.Connection knowing that it will be disposed of 
} 

Примечание - using блок все равно будет работать, если new DbConn() заменяется заводским способом или Property Get - это просто гарантирует, что Dispose() вызывается на объекте когда происходит блокировка выходов, и даже если возникает исключение.

Делая это, вы обойдете все проблемы, которые я выделил в первой половине моего ответа.

+0

но не будет ли это результатом каждого запроса, используя его собственное соединение? Я предпочел бы привязать самое DB-соединение к жизненному DBQuery (таким образом, я могу повторно использовать 1 соединение для нескольких запросов.) Но есть ли «чистый» способ обойти это без того, чтобы обернуть ВСЕ использование DBQuery в 'using' блок? – Raystorm

+0

, только если вы напишете код таким образом - нет ничего, что останавливало бы повторное использование одного и того же соединения для нескольких запросов. Что касается необходимости обойти «использование», зачем вам это нужно? Речь идет не об условности, а о правильном использовании объекта *. Посмотрите на Linq на SQl, Entity Framework и другие ORM - они почти все требуют использования шаблона 'use', потому что это * правильный * способ поговорить с базой данных. Правильная утилизация - это не просто тонкость - сам сервер должен знать, что вы сделали с ним, чтобы он мог обслуживать других клиентов на других БД –

+0

, просто для ясных команд также реализуют IDisposable. –

0

Инфраструктура делает соединение управление (включая объединение) за кулисами, поэтому моя рекомендация держит ваш код чистым, не делая его статичным.