2010-06-05 2 views
1

В настоящее время мы используем NHibernate для сопоставления бизнес-объектов с таблицами базы данных. Указанные бизнес-объекты обеспечивают соблюдение бизнес-правил: аксессоры набора будут выставлять исключение на месте, если контракт на это имущество нарушен. Кроме того, свойства обеспечивают связь с другими объектами (иногда двунаправленными!). Ну, всякий раз, когда NHibernate загружает объект из базы данных (например, когда вызывается ISession.Get (id)), набор аксессуаров сопоставленных свойств используется для помещения данных в объект.Какие классы следует сопоставлять с NHibernate?

Хорошо, что средний уровень приложения обеспечивает бизнес-логику. Плохо то, что в базе данных нет. Иногда дерьмо находит свой путь в базе данных. Если в приложение загружается дерьмо, он освобождает (генерирует исключение). Иногда это явно должно залогодержаться, потому что он ничего не может сделать, но что, если он может продолжать работать? Например, средство администрирования, которое собирает отчеты в режиме реального времени, имеет высокий риск неудачи без необходимости, а не позволяет администратору даже исправить (потенциальную) проблему.

У меня нет примера на мне прямо сейчас, но в некоторых случаях, позволяя NHibernate использовать свойства «входной двери», которые также обеспечивают соблюдение отношений (особенно bidi), приводит к ошибкам.

Каковы наилучшие решения?

В настоящее время я, на основе каждой собственности, создать «заднюю дверь» только для NHibernate:

public virtual int Blah {get {return _Blah;} set {/*enforces BR's*/}} 
protected virtual int _Blah {get {return blah;} set {blah = value;}} 
private int blah; 

я показал выше, в C# 2 (свойств не по умолчанию), чтобы продемонстрировать, как это становится нас в основном 3 слоя, или взглядов, к бла-бла !!! Хотя это, безусловно, работает, оно не кажется идеальным, так как BL требует предоставить один (общедоступный) интерфейс для приложения в целом и другой (защищенный) интерфейс для уровня доступа к данным.

Существует дополнительная проблема: Насколько я знаю, NHibernate не дает вам возможности различать имя свойства в BL и имя свойства в модели сущности (то есть имя, которое вы используете, когда вы запрос, например, через HQL - всякий раз, когда вы даете NHibernate имя (строка) свойства). Это становится проблемой, когда сначала BR для некоторого свойства Blah не проблема, поэтому вы ссылаетесь на него в своем сопоставлении O/R ... но потом вам нужно добавить некоторые BR, которые действительно становятся проблемой, поэтому то вам нужно изменить свое сопоставление O/R, чтобы использовать новое свойство _Blah, которое разбивает все существующие запросы с помощью «Бла» (общая проблема с программированием против строк).

Кто-нибудь решил эти проблемы ?!

+2

Это не понятно, почему вы не можете предотвратить неверные данные от попадания в вашу базу данных. Я не думаю, что обходной путь общего назначения для этого сценария (независимо от того, задействован ли NHibernate или нет). Возможно, вы можете постоянно опробовать базу данных, ищущую недействительные данные, а затем попытаться ее исправить, прежде чем NHibernate попытается загрузить ее. –

+0

Только что нашел связанное обсуждение: http://stackoverflow.com/questions/129773/nhibernate-map-to-fields-or-properties – apollodude217

+0

@Michael: Хороший вопрос/комментарий.Как правило, это устаревшее приложение, в котором существующие данные не отвечают требованиям бизнеса (я знаю, что мы должны его очистить) или где другое устаревшее приложение позволяет получить плохие данные. – apollodude217

ответ

3

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

В приведенном выше примере вам не нужно определять дополнительное защищенное свойство. Просто используйте это в отображении:

<property name="Blah" access="nosetter.lowercase"/> 

Это описано в документации, http://nhibernate.info/doc/nh/en/index.html#mapping-declaration-property (. Таблица 5.1 Стратегии доступа)

+1

Это фактически предпочтительная стратегия доступа для Hibernate: бизнес-правила должны не следует применять при чтении из базы данных, вы должны просто получить то, что в нем. По какой-то причине ребята из NHibernate не согласны и рекомендуют/рекомендуют стратегию доступа к собственности. –

+1

@ Исправлено, вероятно, из-за того, что сеттер обычно не содержит правил, применяемых в .NET/NHibernate. Фактически, большинство постоянных объектов используют автоматические свойства, поэтому генерируются тела геттера/сеттера. –

+0

Спасибо за ваши комментарии! @Diego, Мне кажется, что это решение сократило бы взгляды на Blah в коде C# 2 (просто свойство и поле). Но в C# 3 он должен потребовать, чтобы у меня было 2 уровня для начала (свойство и поле) - то есть, Blah не может быть свойством по умолчанию; он должен быть закодирован вручную, существует ли какая-либо бизнес-логика для реализации или нет. Правильно ли я понимаю? – apollodude217

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