在NHibernate中同时保存多个子实体

在NHibernate中同时保存多个子实体,nhibernate,fluent-nhibernate,s#arp-architecture,Nhibernate,Fluent Nhibernate,S#arp Architecture,我得到了NHibernate中的“保存未保存的瞬态实体”错误。我有一个聚合根,邻居,它包含地址和人,下面是一些快速的伪代码来解释这种关系: public class Neighborhood { public virtual int Id { get; set; } public virtual IList<Address> Addresses { get; set; } } public class Address { public virtual int Id

我得到了NHibernate中的“保存未保存的瞬态实体”错误。我有一个聚合根,
邻居
,它包含
地址
,下面是一些快速的伪代码来解释这种关系:

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; }
}
在我的代码中,我经常希望创建一个地址,同时将地址和人员关联起来:

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();
我将在
个人
实体上获得“未保存的临时实体”错误,因为它附加到临时实体
地址

我能看到的唯一方法是首先保存
地址
,在更新后再次调用数据库更新
邻居
,搜索我刚刚添加的
地址
,附加
人员
,然后再次保存


我有没有遗漏什么让这更容易?这似乎是一个常见的用例,我不想对数据库进行多次往返。

请确保将从地址到人员的映射的“级联”属性设置为“保存更新”或“全部”。你有从邻居到地址的级联,但你没有说这个较低的级联存在。如果不是,那么您得到这个错误不是因为某人附加到一个临时地址,而是因为该地址引用了一个临时人


如果由于任何原因无法进行此级联,请先保存此人,然后保存邻居,这将级联到地址,ORM将在其会话中找到被引用的人并设置引用。这可能会导致一些额外的“往返”,具体取决于您是让NH还是DB生成自动编号列。NHibernate很棘手,因为它会在状态良好且准备就绪时进行DB调用,这可能是在整个对象图处于NH会话中之后,或者只是在人之后。无论哪种方式,它都会为每个被持久化的对象向DB中发出一个Insert调用,因此无论向会话中添加项目的代码是什么样的,它都会进行多次“往返”。

请确保将从地址到人的映射的“级联”属性设置为“保存更新”或“全部”。你有从邻居到地址的级联,但你没有说这个较低的级联存在。如果不是,那么您得到这个错误不是因为某人附加到一个临时地址,而是因为该地址引用了一个临时人

如果由于任何原因无法进行此级联,请先保存此人,然后保存邻居,这将级联到地址,ORM将在其会话中找到被引用的人并设置引用。这可能会导致一些额外的“往返”,具体取决于您是让NH还是DB生成自动编号列。NHibernate很棘手,因为它会在状态良好且准备就绪时进行DB调用,这可能是在整个对象图处于NH会话中之后,或者只是在人之后。无论哪种方式,它都会为每个被持久化的对象向DB中发出一个Insert调用,因此无论将项添加到会话中的代码是什么样子,它都会发出多个“往返”

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();