C# NHibernate在集合插入时强制生成Guid
我想在聚合根目录中添加一个新实体。这很好,但不强制生成Id 为了让它更清楚,请看下面的示例代码,其中所有实体都映射为C# NHibernate在集合插入时强制生成Guid,c#,nhibernate,fluent-nhibernate,domain-driven-design,C#,Nhibernate,Fluent Nhibernate,Domain Driven Design,我想在聚合根目录中添加一个新实体。这很好,但不强制生成Id 为了让它更清楚,请看下面的示例代码,其中所有实体都映射为Id(e=>e.Uid) public class Aggregate : EntityBase<Guid,Aggregate> { // ... public virtual ISet<SubEntity> SubEntities { get; protected set; } public virtual SubEntity DoSo
Id(e=>e.Uid)代码>
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);
公共类聚合:EntityBase
{
// ...
公共虚拟ISet子实体{get;protected set;}
公共虚拟子实体doSomethingthatscreatesSubentity(字符串名称,字符串格式)
{
var newEntity=新的子实体(名称、格式);
子实体。添加(新实体);
返回新实体;
}
}
公共类子实体:EntityBase
{
}
//客户端代码:
var agr=Session.Get(id);
var subEntity=agr.dosomethingthatscreatesasubentity(“xyz”、“xyz”);
断言.True(子实体.IsTransient);
Session.Flush();
Assert.False(子实体.IsTransient);
我想要的是,当我添加到子实体时,newEntity将用Uid重新加载。
我不想访问那里的NHibernate会话(因此无法访问Session.Save()或Refresh())
在不修改我的实体的情况下,这是可能的吗?我认为您有两种选择:
保存前手动分配id。在这种情况下,除非添加版本
或时间戳
列,否则NHibernate将无法检测到它是一个新实体
从您的方法返回子实体
本身(毕竟,在DDD中,为什么要传递GUID?)在会话结束时保存聚合根后,任何包含该子实体引用的内容都将获得最新的id。据推测,在控制传回前端代码之前,会话将被刷新,这是需要id的地方,但是调用代码需要知道,在会话中途提取id是个坏主意
您可以手动生成id(将id生成器设置为分配)然后,每次创建一个新实体时,都应该设置其id,这样应用程序中就可以使用该id,而无需使用ISession。以后,可以使用ISession将该对象保存到数据库中。这种方法的唯一问题是NHibernate不知道创建了哪个对象,更新了哪个对象(您不能使用会话的SaveOrUpdate方法)您应该显式地使用Save和Update方法,或者您可以插入一个拦截器,该拦截器使用一个逻辑来查看对象是否被更新或插入,然后您可以再次使用SaveOrUpdate。关于不传递Guid的说法是正确的(我使用域事件来驱动事务资源…)。我只需保留对“newEntity”的引用,直到刷新会话。之后,Uid设置正确。