В настоящее время мы используем 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» (обычная проблема при программировании со строками).
Кто-нибудь решил эти проблемы ?!