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

时间:2012-02-20 16:19:49

标签: c# nhibernate fluent-nhibernate domain-driven-design

我想在我的聚合根中添加一个新实体。这样可以正常工作,但不会强制生成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时,将使用Uid重新加载newEntity。 我不想在那里访问NHibernate ISession(因此Session.Save()或Refresh())是遥不可及的。

这可以在不修改我的实体的情况下实现吗?

2 个答案:

答案 0 :(得分:0)

我认为你有两个选择:

  1. 保存前手动分配ID。在这种情况下,除非您添加VersionTimestamp列,否则NHibernate将无法检测到它是新实体。 See here

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

答案 1 :(得分:0)

您可以手动生成ID(将id生成器设置为assign),然后每次创建新实体时都应设置其ID,并且您将在应用程序中使用此ID而不使用ISession.Later您可以使用ISession来保存它这个方法的唯一问题是NHibernate不会知道哪个对象被创建以及哪个对象被更新(你不能使用SaveOrUpdate会话方法)你应该明确地使用Save和Update方法,或者你可以插入一个使用逻辑的拦截器来查看对象是否已更新或插入,然后您可以再次使用SaveOrUpdate。