2010-05-12 8 views
1

Что бы ваш подход с NHibernate сделать следующее:
Когда Comment вставляется в БД, а его свойство Text вставляется в столбец Text (из-за отображения), вставить в столбец TextHash хэш этого значения свойства.NHibernate: вставив дополнительный вычисляемый столбец

Это кажется тривиальным, если я нахожу карту TextHash, но как мне это сделать без отображения?
Мне не нужна эта модель в домене, ее оптимизация уровня DB (я бы использовал рассчитанные HashBytes, если не для ограничения длины).

ответ

1

Есть некоторые подобные вопросы, такие, как этот:
Unmapped Columns in NHibernate?

Однако, IInterceptor кажется переполненным для изменения в единственной вставке объекта. И EventListeners являются менее совершенными документами, а также несколько сложными для одного столбца.

Так что я решил на решении, которое я вижу, как в качестве наиболее многоразовых и локальнейшего:

<property name="Text" type="StringWithMD5HashUserType"> 
    <column name="Text" length="20000" not-null="true" /> 
    <column name="TextHash" length="32" not-null="true" /> 
    </property> 

Где StringWithMD5HashUserType является ICompositeUserType, который читает Text из первого столбца, но пишет как Text и его Hash (я не добавляйте код StringWithMD5HashUserType, потому что он слишком длинный, но по сути очень простой).

0

Ну, если вы не хотите использовать это свойство, объявите его приватным и вычислите его, когда вы установите свойство text. Это не совсем «без сопоставления», но вы не увидите его, когда используете класс (отказ от ответственности: совет, основанный на Hibernate, в отличие от NHibernate).

Кроме этого, вы всегда можете написать триггер, хотя лично я бы скорее добавил частное поле и покончил с ним.

+0

Я знаю, что могу использовать частный, но это не совсем упорство, невежественное. Так что это вроде как против сильных сторон NH, как я их вижу. –

+0

Боюсь, я не вижу недостатка в объявлении частного поля. Семантически, объявляя это таким образом, вы, в основном, говорите, что это «локальная деталь реализации», она «не должна использоваться извне сущности», а остальная часть приложения остается блаженно не осведомленной о вычисленном поле. Вам нужно поместить логику хэширования _somewhere_, и я могу думать только о двух местах: модели и базе данных. Во всяком случае, не стесняйтесь пренебрегать. :) –

+0

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

0

Вот предложение: Насколько я знаю, вы не можете получить доступ к столбцу в своей БД с помощью NHibernate, если для него не определено отображение. Чтобы другие части вашего приложения, чтобы увидеть это поле вашего класса вы можете определить ее доступ как поле в вашем отображении, так что это может быть частным никто не знает, что она существует, но NHibernate: В своем классе:

private string _textHash 

В вашем отображении:

<property name='_textHash' column='TextHash' access='field' /> 
+0

Ну, это практически то же, что предлагает Томислав. Он имеет те же проблемы: связывает сущность с алгоритмом хеширования, который действительно представляет собой реализацию, связывает сущность с структурой БД. Кроме того, частное поле, которое никто не использует, имеет большую вероятность быть удаленным разработчиками, работающими с Resharper. –

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