NHibernate:保存瞬态实例时,身份ID如何更新?

如果我使用session-per-transaction并调用:

session.SaveOrUpdate(实体) 更正:
session.SaveOrUpdateCopy(实体)

..and entity是identity-Id = 0的瞬态实例。 以上行是否会自动更新实体的Id,并使实例持久化? 或者它应该在transaction.Commit上这样做吗? 或者我必须以某种方式明确地编码?

显然,数据库行的Id(新的,因为瞬态)是自动生成的并保存为某个数字,但我在这里谈论的是实际的参数实例。 哪个是业务逻辑实例。


编辑 – 跟进,相关问题。

映射:

public class StoreMap : ClassMap { public StoreMap() { Id(x => x.Id).GeneratedBy.Identity(); Map(x => x.Name); HasMany(x => x.Staff) // 1:m .Cascade.All(); HasManyToMany(x => x.Products) // m:m .Cascade.All() .Table("StoreProduct"); } } public class EmployeeMap : ClassMap { public EmployeeMap() { Id(x => x.Id).GeneratedBy.Identity(); Map(x => x.FirstName); Map(x => x.LastName); References(x => x.Store); // m:1 } } public class ProductMap : ClassMap { public ProductMap() { Id(x => x.Id).GeneratedBy.Identity(); Map(x => x.Name).Length(20); Map(x => x.Price).CustomSqlType("decimal").Precision(9).Scale(2); HasManyToMany(x => x.StoresStockedIn) .Cascade.All() .Inverse() .Table("StoreProduct"); } } 

EDIT2

类定义:

  public class Store { public int Id { get; private set; } public string Name { get; set; } public IList Products { get; set; } public IList Staff { get; set; } public Store() { Products = new List(); Staff = new List(); } // AddProduct & AddEmployee is required. "NH needs you to set both sides before // it will save correctly" public void AddProduct(Product product) { product.StoresStockedIn.Add(this); Products.Add(product); } public void AddEmployee(Employee employee) { employee.Store = this; Staff.Add(employee); } } public class Employee { public int Id { get; private set; } public string FirstName { get; set; } public string LastName { get; set; } public Store Store { get; set; } } public class Product { public int Id { get; private set; } public string Name { get; set; } public decimal Price { get; set; } public IList StoresStockedIn { get; private set; } } 

就您的问题而言,每当您刷新会话时,您的实体都会持久保存到数据库。 保存(新)实体时,NHibernate会使用您提供的生成器为您生成ID。

请记住,不建议使用Identity生成器(请参阅Ayende的这篇文章 )。 使用Identity生成器时,即使未刷新到数据库,新实体也会在保存时保留到数据库中。 发生这种情况的原因是因为NHibernate需要为您提供实体的ID,如果不对数据库进行往返,它就无法做到。

更好的解决方案是使用像Guid生成器或HiLo这样的东西,如果你想要“正常”值。 通过这种方式,您可以保存实体,而无需实际进行数据库往返,这样可以更好地执行更多性能(请记住批处理)。

我不确定我理解你的问题。 在刷新会话时(例如,通过提交事务),实际保存到数据库。 调用SaveOrUpdate()本身并不保存实体,它只是通知会话在刷新会话时要保存实体。

假设实体的ID映射到数据库中的标识字段,并且您的映射告诉NHibernate该标识是由数据库设置的,那么数据库设置的ID将在保存时设置为实体的ID。

Nhibernate将在SaveOrUpdate调用之后设置实体的ID属性。

我注意到我通过以下方式保存:

 session.SaveOrUpdateCopy(entity); 

..不会更新ID。 但是改为:

 session.SaveOrUpdate(entity); 

..瞬态实体的Id 被更新。

我可能误解了文档(?)..第9.4.2节说:

SaveOrUpdateCopy(Object o)…如果给定的实例未保存或数据库中不存在,NHibernate将保存它并将其作为新的持久化实例返回。

它只是我,还是听起来不像一个瞬态对象( 未保存 ),将“ 作为持久性返回 ? 这是不是意味着更新的ID? 希望澄清如何正确解释这句话(?)