同时插入NHibernate的父级和子级

Dan*_*Dan 10 nhibernate fluent-nhibernate

我试图保存(插入)具有列表子实体的父实体.两个人都使用Guid作为主键.密钥不可为空,并且db中没有设置密钥关系.

保存不起作用,抛出一个异常声明 - 我试图将null保存到Child表中的Parent外键中.

我期待nhibernate为Parent创建一个键,让它的Child对象知道它.这是NHibernate的限制还是使用Guids作为主键?

这个答案表明你必须设置父母,这真的是唯一的方法吗?

以下是我的映射供参考:

父映射:

HasMany(x => x.Children).KeyColumn("ParentKey").Inverse().Cascade.All();
Run Code Online (Sandbox Code Playgroud)

子映射:

 References(x => x.Parent).Not.Nullable().Column("ParentKey");
Run Code Online (Sandbox Code Playgroud)

doc*_*tan 15

NHibernate并不神奇.它只是一个ORM,如果您的孩子没有将他们的参考设置为父母,为什么它会假设因为父母有一个孩子的列表,孩子的参考,反过来,应该是对父母的引用?

当你声明Child实体没有填充其Parent属性时,我相信你回答了你自己的问题(这意味着它是null,这意味着NHibernate将试图在你的Child表中保存Parent id的'null'值).

如果您要使用WITHETE NHibernate这些对象,那么在添加它们时需要在Child实体上设置Parent引用是有意义的.

编辑: 这是您在映射上指定"反向"的情况.如果您要将此调用移除为"反向",它应该按您希望的方式工作,因为反向声明另一端(子实体)负责跟踪关系.这意味着您需要手动设置子项上父项的引用.

但是,删除Inverse语句将导致保存Child(ren),保存父级,然后将Child(ren)的父ID更新为UPDATED.由于您对父ID具有空约束,这意味着它仍然无法正常工作,因为它最初会插入父ID为null的Child.

这两个解决方案是删除此约束,或者只是向Parent添加一个名为AddChild的方法:

public void AddChild(Child childObj)
{
    childObj.Parent = this;
    Children.Add(childObj);
}
Run Code Online (Sandbox Code Playgroud)

添加另一个名为RemoveChild的方法:

public void RemoveChild(Child childObj)
{
    if (Children.Contains(childObj))
    {
        Child.Parent = null;
        Children.Remove(childObj);
    }
}
Run Code Online (Sandbox Code Playgroud)

然后,只需使用这些方法添加/删除子项.