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()无法访问。
在不修改我的实体的情况下,这可能吗?
我认为您有两个选项:
-
保存前手动分配id。在这种情况下,除非添加
Version
或Timestamp
列,否则NHibernate将无法检测到它是一个新实体。请参见此处。 -
从方法返回
SubEntity
本身(毕竟,在DDD中,为什么要传递GUID?)在会话结束时保存聚合根后,任何引用该子实体的对象都将获得最新的id。据推测,在控制权传递回前端代码之前,会话将被刷新,前端代码是需要id的地方,但调用代码需要意识到,在会话中途提取id是个坏主意。
您可以手动生成id(设置要分配的id生成器),然后每次创建新实体时,都应该设置其id,这样您就可以在应用程序中使用此id,而无需使用ISession。稍后,您可以使用ISession将此对象保存到数据库中。这种方法的唯一问题是,NHibernate不知道创建了哪个对象,更新了哪个对象(您不能使用会话的SaveOrUpdate方法)。您应该显式使用Save和Update方法,或者您可以插入一个拦截器,该拦截器使用逻辑来查看对象是否更新或插入,然后您可以再次使用SaveOrUpdate。