【问题标题】:NHibernate force Guid generation at collection insertNHibernate force Guid 在集合插入时生成
【发布时间】:2012-02-20 16:19:49
【问题描述】:

我想在我的聚合根中添加一个新实体。这可以正常工作,但不会强制生成 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);

我想要的是,当我添加到子实体时,newEntity 将使用 Uid 重新加载。 我不想在那里访问 NHibernate ISession(所以 Session.Save() 或 Refresh())是遥不可及的。

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

【问题讨论】:

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


    【解决方案1】:

    我认为你有两个选择:

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

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

    【讨论】:

    • 你没有通过 Guid 是对的(我正在使用域事件来驱动事务资源......)。我只需要保留对“newEntity”的引用,直到会话被刷新。之后 Uid 设置正确。
    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-10-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-02
      • 2015-05-15
      • 2011-03-11
      相关资源
      最近更新 更多