NHibernate / ActiveRecord - есть ли способ сопоставить только столбец внешнего ключа? - PullRequest
0 голосов
/ 29 октября 2008

Я использую Castle ActiveRecord, но этот вопрос относится и к NHibernate, так как решение, которое работает с NHibernate, должно работать для ActiveRecord. Во всяком случае, у меня есть базовая структура таблицы, как это:

Таблица A -hasMany-> Таблица B

У меня есть соответствующие объекты EntityA и EntityB. EntityA имеет список объектов EntityB. Эта часть отлично работает. Теперь я хочу, чтобы у EntityB была какая-то ссылка на EntityA. Я знаю, что могу использовать атрибут BelongsTo на EntityB, чтобы дать ему фактическую ссылку на полный тип EntityA, например:

[BelongsTo("tableAid")]
public EntityA Parent { get; set; }

Но то, что я действительно хотел бы сделать, это:

[BelongsTo("tableAid")]
public int ParentId { get; set; }

Итак, EntityB будет хранить только идентификатор родительского объекта, а не ссылку на реальный объект. Это тривиальный пример, но у меня есть веские причины желать использовать этот подход. В приложении, над которым я работаю, у нас есть страницы, которые отображают определенные EntityB-подобные объекты, и мы хотели бы, чтобы эти страницы включали ссылки (как в гиперссылках) на соответствующие родительские страницы. Мы можем сделать это, используя первый подход, описанный выше, но для этого требуется, чтобы весь объект EntityA был загружен, когда все, что мне действительно нужно, это идентификатор. Это не большое дело, но это просто кажется расточительным. Я знаю, что могу использовать ленивую загрузку, но опять же, это больше похоже на хак ...

Я попытался пометить внешний ключ атрибутом [Property] следующим образом:

[Property]
public int ParentId { get; set; }

Проблема этого подхода заключается в том, что EntityB.ParentId остается нулевым, когда вы выполняете EntityA.SaveAndFlush () в новом дереве объектов. Правильное значение записывается в базу данных, и я могу принудительно вернуть значение обратно в EntityB.ParentId, выполнив EntityA.Refresh (), но опять же, это похоже на хак.

Ответы [ 2 ]

2 голосов
/ 03 мая 2009

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

Если бы вы пометили свой «родительский» EntityA как загруженный с отложенным доступом, ссылка на EntityB.Parent.Id вообще не загрузила бы EntityA (как за кулисами NHIbernate уже загрузил идентификатор EntityA при загрузке EntityB) - таким образом, вы можете настроить Ваши ссылки без ущерба для производительности.

0 голосов
/ 29 октября 2008

Только так:

[Property] public int ParentId { get; set; }

... при условии ParentId - фактическое имя столбца.

Пара других комментариев.

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

Во-вторых, имейте в виду, что всякий раз, когда у вас есть связь один-ко-многим без соответствующего отношения от ребенка к родителю, вы должны сделать FK обнуляемым в базе данных. Это потому, что когда NH создает новые дочерние элементы, он вставляет его с идентификатором родителя, равным NULL, а затем на втором этапе обновляет его.

...