2009-03-28 1 views
3

Мне обычно нравится создавать соединение с базой данных самостоятельно и вручную контролировать ее время жизни с помощью `using {} '. Например:Чтобы инкапсулировать подключение к базе данных в бизнес-объектах или нет?

SqlConnection sqlConnection = new SqlConnection(connectionString); 
using(sqlConnection) { 
    BusinessObject myBusinessObject = new BusinessObject(sqlConnection); 
    // do stuff with the business object 
    ... 
} 

Таким образом, очевидно, что я использую ресурс, который необходимо очистить соответствующим образом. Однако это приводит к множеству повторяющихся усилий. Я соблазн создать соединение Sql внутри бизнес-объекта и реализовать IDisposable на нем. Я бы закрыл соединение в методе Dispose().

using(BusinessObject myBusinessObject = new BusinessObject()) { 
    // do stuff with myBusinessObject 
    ... 
} 

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

Как вы, ребята, это сделаете?

ответ

4

Бизнес-объекты должны быть разумно (или полностью) глупыми относительно базы данных. Вы должны реализовать какой-то объект уровня доступа (репозиторий или контекст данных), который знает, как сохранить ваши бизнес-объекты в базе данных и сохранить логику соединения, а не помещать код в каждый из ваших бизнес-объектов. Ваш репозиторий или контекст будет одноразовым, чтобы он мог очищаться после себя. Предложение Марка о том, что вы следуете шаблону «Единица работы», является хорошим.

Возможно, вы захотите взглянуть на LINQtoSQL, nHibernate, Subsonic и т. Д., Чтобы использовать их или, по крайней мере, для идей о том, как структурировать хороший уровень данных, если вы настаиваете на написании своих собственных. Из личного опыта я могу сказать вам, что использование существующей технологии намного проще, чем писать и поддерживать свои собственные.

+0

Спасибо за ответ. Код, о котором я сейчас думаю, довольно прост. Я использовал NHibernate в прошлом, не уверен, что хочу пойти туда для этого проекта. Но, как вы сказали, может быть, прокрутка источника будет хорошим упражнением. – dnewcome

+0

Если nHibernate кажется слишком большим, то рассмотрим LINQtoSQL. По моему опыту это очень легкий вес.Вы можете либо рассматривать объекты L2S как DTO, либо расширять их с помощью частичных классов/методов в полноценные бизнес-объекты. – tvanfosson

3

Ну, во-первых, я оставил бы подключения к репозиторию.

Во-вторых, я бы не поддерживал соединение на объекте - я использовал бы его только для единицы работы (т. Е. Одного метода). Вероятно, что (из-за объединения) вы все равно получите физическое соединение. Система уже имеет большое значение для обработки таких вещей, чтобы вам не приходилось это делать.

Более сложный случай - транзакции, где TransactionScope намного проще, чем передавать объект транзакции db.

+0

Я соглашаюсь поддерживать связь. Я бы сохранил время существования бизнес-объекта так же, как я бы использовал созданное вручную соединение. Проблема в том, что другие, которые используют API, могут не работать. Может быть, создать/закрыть соединение при звонках в BO? Но тогда, может быть, нам понадобится транс. позже. – dnewcome

+0

@Marc. У меня было менее звездное впечатление от TransactionScope, хотя с LINQToSQL может быть лучше. В любом случае при использовании TableAdapters я бы обнаружил, что почти все транзакции будут распространяться на распределенные транзакции и не имеют никаких проблем, связанных с тем, что он работает через брандмауэр в БД. – tvanfosson

+0

@tvanfosson - хорошая обратная связь; как говорится: YMMV ;-p –

0

Я не думаю, что бизнес-объект должен знать или заботиться о том, является ли он постоянным. Индивидуальный постоянный бизнес-объект не может знать, когда он является частью большей единицы работы; это ответственность сервисного уровня. Оставьте соединение с бизнес-объектами. Уровень обслуживания - это подходящее место для получения соединений, как правило, из пула соединений, установки границ транзакций, фиксации или отката и очистки.

Смежные вопросы