NHibernate强制在集合插入时生成Guid

本文关键字:Guid 插入 集合 NHibernate | 更新日期: 2023-09-27 18:25:23

我想在我的聚合根中添加一个新实体。这很好,但不会强制生成Id。

为了使其更加清晰,请参阅以下示例代码,其中所有实体都使用Id(e => e.Uid).GeneratedBy.GuidComb();进行映射。

public class Aggregate : EntityBase<Guid,Aggregate>
{
   // ...
   public virtual ISet<SubEntity> SubEntities { get; protected set; }
   public virtual SubEntity DoSomethingThatCreatesASubEntity(string name, string format)
   {
       var newEntity=new SubEntity(name, format);
       SubEntities.Add(newEntity);
       return newEntity;
   }
}
public class SubEntity : EntityBase<Guid,SubEntity>
{
}
// Client Code:
var agr=Session.Get<Aggregate>(id);
var subEntity=agr.DoSomethingThatCreatesASubEntity("xyz","xyz");
Assert.True(subEntity.IsTransient);
Session.Flush();
Assert.False(subEntity.IsTransient);

我想要的是,当我添加到SubEntites时,newEntity将重新加载Uid。我不想访问那里的NHibernate ISession(因此Session.Save()或Refresh()无法访问。

在不修改我的实体的情况下,这可能吗?

NHibernate强制在集合插入时生成Guid

我认为您有两个选项:

  1. 保存前手动分配id。在这种情况下,除非添加VersionTimestamp列,否则NHibernate将无法检测到它是一个新实体。请参见此处。

  2. 从方法返回SubEntity本身(毕竟,在DDD中,为什么要传递GUID?)在会话结束时保存聚合根后,任何引用该子实体的对象都将获得最新的id。据推测,在控制权传递回前端代码之前,会话将被刷新,前端代码是需要id的地方,但调用代码需要意识到,在会话中途提取id是个坏主意。

您可以手动生成id(设置要分配的id生成器),然后每次创建新实体时,都应该设置其id,这样您就可以在应用程序中使用此id,而无需使用ISession。稍后,您可以使用ISession将此对象保存到数据库中。这种方法的唯一问题是,NHibernate不知道创建了哪个对象,更新了哪个对象(您不能使用会话的SaveOrUpdate方法)。您应该显式使用Save和Update方法,或者您可以插入一个拦截器,该拦截器使用逻辑来查看对象是否更新或插入,然后您可以再次使用SaveOrUpdate。