Одновременное сохранение нескольких дочерних объектов в NHibernate - PullRequest
0 голосов
/ 20 сентября 2010

Я получаю сообщение об ошибке «Сохранить несохраненные временные объекты» в NHibernate. У меня есть совокупный корень, neighborhood, который содержит addresses и person, вот несколько быстрых псевдокодов для объяснения взаимосвязи:

public class Neighborhood {
   public virtual int Id { get; set; }
   public virtual IList<Address> Addresses { get; set; }
}

public class Address {
   public virtual int Id { get; set; }
   public virtual string Address { get; set; }
   public virtual Person Person { get; set; } //Assume only one person per address
}

public class Person {
   public virtual int Id { get; set; }
   public virtual string Name { get; set; }
}

На моей карте Соседства есть:

   mapping.HasMany(x => x.Addresses)
        .Inverse()
        .KeyColumn("NeighborhoodFk")
        .Cascade.All()
        .AsBag();

В моем коде я часто хочу создать и связать адрес и человека одновременно:

var address = new Address();
var person = new Person();

var address.Person = person;

var neighborhood = neighborhoodRepository.Get(id);

neighborhood.Add(address);

neighborhoodRepository.DbContext.BeginTransaction();
neighborhoodRepository.SaveOrUpdate(neighborhood);
neighborhoodRepository.DbContext.CommitTransation();

Я получу ошибку «несохраненные переходные объекты» для объекта Person, поскольку он присоединен к переходному объекту Address.

Единственный способ убедиться в этом - сначала сохранить address, еще раз вызвать базу данных для обновления neighborhood после обновления, найти только что добавленный address, прикрепить person и затем сохраните снова.

Что-то мне не хватает, чтобы сделать это проще? Это похоже на общий случай использования, и я не хочу делать кучу обходов в базу данных.

1 Ответ

5 голосов
/ 20 сентября 2010

Убедитесь, что вы устанавливаете атрибут «Каскад» при сопоставлении адреса с человеком на «сохранить-обновить» или «все». У вас есть каскад от Соседства до Адреса, но вы не утверждали, что этот нижний каскад присутствовал. Если это не так, вы получаете эту ошибку не потому, что Персона присоединена к временному адресу, а потому, что Адрес ссылается на временного Персона.

Если этот каскад не может быть выполнен по какой-либо причине, сначала сохраните Person, затем сохраните Соседство, которое будет каскадно адресоваться, и ORM найдет связанного Person в своем сеансе и установит ссылку. Это МОЖЕТ привести к некоторым дополнительным «обходам» в зависимости от того, позволяете ли вы NH или DB генерировать столбцы автономного номера. NHibernate хитр в том, что он будет делать вызовы БД, когда все будет хорошо и готово, и это может произойти после того, как весь объектный граф будет в сеансе NH, или только человек. В любом случае, он будет вызывать вставку в БД для каждого сохраняемого объекта, поэтому он будет совершать несколько «циклических циклов» независимо от того, как выглядит код для добавления элементов в сеанс.

...