在NHibernate中同时保存多个子实体
我得到了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
邻居
,它包含地址
和人
,下面是一些快速的伪代码来解释这种关系:
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();