【问题标题】:Saving multiple child entities in NHibernate, at once一次在 NHibernate 中保存多个子实体
【发布时间】:2010-09-20 17:27:44
【问题描述】:

我在 NHibernate 中收到“保存未保存的临时实体”错误。我有一个聚合根 neighborhood,其中包含 addressesperson,这里有一些快速的伪代码来解释这种关系:

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然后再次保存。

我是否缺少一些东西来使这更容易?这似乎是一个常见的用例,我不想对数据库进行大量往返。

【问题讨论】:

    标签: nhibernate fluent-nhibernate s#arp-architecture


    【解决方案1】:

    确保您将从地址到人员的映射的“级联”属性设置为“保存更新”或“全部”。你有从 Neighborhood 到 Address 的级联,但你没有说明这个较低的级联存在。如果不是,您收到此错误不是因为 Person 附加到临时地址,而是因为地址引用了临时人员。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多