Какие классы следует сопоставить с NHibernate?

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

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

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

Какие есть лучшие решения?

В настоящее время я буду создавать «черный ход» для каждого свойства только для 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, которое разбивает все существующие запросы с помощью «Blah» (обычная проблема при программировании со строками).

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


person jyoungdev    schedule 05.06.2010    source источник
comment
Непонятно, почему вы не можете предотвратить попадание недействительных данных в вашу базу данных. Я не думаю, что для этого сценария существует обходной путь общего назначения (независимо от того, задействован NHibernate или нет). Возможно, вы могли бы постоянно опрашивать базу данных в поисках недействительных данных, а затем как-то пытаться исправить их, прежде чем NHibernate попытается ее загрузить.   -  person Michael Maddox    schedule 05.06.2010
comment
Только что нашел соответствующее обсуждение: stackoverflow.com/ вопросы / 129773 /   -  person jyoungdev    schedule 07.06.2010
comment
@Michael: Хороший вопрос / комментарий. Как правило, это устаревшее приложение, в котором существующие данные не соответствуют бизнес-требованиям (я знаю, что мы должны их очистить) или где другое устаревшее приложение допускает попадание неверных данных.   -  person jyoungdev    schedule 07.06.2010


Ответы (1)


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

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

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

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

person Diego Mijelshon    schedule 05.06.2010
comment
На самом деле это предпочтительная стратегия доступа для Hibernate: бизнес-правила не должны применяться при чтении из базы данных, вы должны просто получить то, что в ней. По какой-то причине ребята из NHibernate не согласны и не рекомендуют стратегию доступа к собственности. - person Fried Hoeben; 06.06.2010
comment
@Fried, вероятно, потому, что сеттер обычно не применяется к правилам .NET / NHibernate. Фактически, большинство постоянных сущностей используют автоматические свойства, поэтому генерируются тела получателя / установщика. - person Diego Mijelshon; 06.06.2010
comment
Спасибо за ваши комментарии! @Diego, мне кажется, что это решение сократит количество представлений до Blah в коде C # 2 (только свойство и поле). Но в C # 3 мне потребуется начать с двух слоев (свойство и поле), т. Е. Blah не может быть свойством по умолчанию; он должен быть написан вручную независимо от того, есть ли бизнес-логика для реализации или нет. Я правильно понял? - person jyoungdev; 07.06.2010
comment
@apollodude Я не понимаю вопроса. Это не подразумевает дополнительного уровня в вашем существующем коде, потому что вы уже используете неавтоматические свойства; вы фактически удаляете слой (защищенное свойство). - person Diego Mijelshon; 07.06.2010
comment
Мне жаль, что это было неясно. Ваш ответ ответил на мой вопрос. Я сказал, что для вашего решения требуется 2, а не то, что больше или меньше. Чтобы уточнить, это меньше, чем в приведенном выше примере C # 2. Однако ваше решение означает, что я не могу начать со свойством по умолчанию (через C # 3). И меня это устраивает. Я просто пытался убедиться, что понял тебя. - person jyoungdev; 07.06.2010
comment
Ваше решение также избавляет от необходимости изменять, например, запросы HQL, когда я добавляю бизнес-логику. Это большая проблема с моим предыдущим решением. - person jyoungdev; 07.06.2010