Обновление отношений «многие к одному» - PullRequest
0 голосов
/ 30 октября 2008

У меня есть объект User, на котором есть объект Country. Я сопоставляю это с тегом «многие к одному» в файле сопоставления пользователей:

<many-to-one name="Country" column="CountryID" cascade="none"/>

Как обновить страну пользователя?

В данный момент в моем пользовательском интерфейсе раскрываются страны, и идентификатор новой страны передается контроллеру. Контроллер затем устанавливает идентификатор страны пользователя из этого значения. Итак:

var user = session.Get<User>(userID);
user.Country.ID = Convert.ToInt32(Request.Form["Country_ID"]);

Но когда я звоню:

session.SaveOrUpdate(user);

Я получаю сообщение об ошибке, в котором говорится, что «идентификатор экземпляра Country был изменен с 7 на 8». Предположительно, это потому, что объект Country помечен как грязный в NHibernate? Я не хочу обновлять объект страны, просто ссылку на идентификатор пользователя. Можно ли сделать это таким образом?

Спасибо, Jon

Ответы [ 5 ]

1 голос
/ 31 октября 2008

Вы всегда можете получить базовое соединение и выполнить обновление вручную.

http://www.darkside.co.za/archive/2008/03/03/castle-activerecord-get-the-underlying-database-connection.aspx

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

Вероятно, вам следует перенести это обсуждение в группу пользователей NHibernate.

http://groups.google.com/group/nhusers

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

Это действительно свело бы на нет всю цель использования ORM, не так ли? Каков нормальный шаблон для обновления дочерних объектов, подобных этому? Конечно, это очень распространенный сценарий. Это загрузить все до:

var user = session.Get<User>(userID);
user.Country = session.Get<Country>(Convert.ToInt32(Request.Form["Country_ID"]));
user.Manager = session.Get<User>(Convert.ToInt32(Request.Form["Manager_ID"]));
user.State = session.Get<State>(Convert.ToInt32(Request.Form["State _ID"]));
user.Region = session.Get<Region>(Convert.ToInt32(Request.Form["State _ID"]));

Нужно ли нам делать дополнительный вызов базы данных для каждого дочернего объекта (событие, хотя эти объекты не обновляются)?

На данный момент имеем:

var ds = new NameValueDeserializer();
var entity = session.Get<TEntity>(entityID);
ds.Deserialize(entity, form);
session.Update(entity);

Так что это работает в общем для всех сущностей. Необходимость специально загружать дочерние объекты для сохранения сущности была бы ненужной затратами на кодирование (а также делать дополнительные вызовы базы данных).

Нет ли способа обойти это в конфигурации, отображениях, перехватчиках и т. Д.? Кто-нибудь знает, почему Hibernate принял это дизайнерское решение?

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

Спасибо, Андерс. Зачем нам нужны дополнительные издержки при первом возвращении объекта, когда все, что мы делаем, это обновляем ссылку на этот объект?

На самом деле наш контроллер автоматически десериализует запрос к объекту. Разве мы не можем сказать NHibernate игнорировать обновление объекта страны и просто обновить пользователя? Я бы подумал, что cascade = "none" сделал бы это.

Что произойдет, если у вас есть несколько объектов «многие к одному» на объекте, которые необходимо обновить? Это слишком много, чтобы вернуть их все перед сохранением.

0 голосов
/ 30 октября 2008
var user = session.Get<User>(userID);
user.Country = session.Get<Country>(Convert.ToInt32(Request.Form["Country_ID"]));

Вы должны извлечь страну из базы данных и затем установить ее для пользователя

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...