同时插入带有NHibernate的父项和子项

同时插入带有NHibernate的父项和子项,nhibernate,fluent-nhibernate,Nhibernate,Fluent Nhibernate,我正试图用列表子实体保存(插入)父实体。两个实体都使用Guid作为主键。密钥不可为null,并且数据库中没有设置密钥关系 保存不起作用,抛出一个异常,声称我正在尝试将null保存到子表的父外键中 我希望nhibernate为父对象创建一个键,并让它的子对象知道它。这是NHibernate的限制还是使用GUID作为主键的限制 这意味着你必须手动设置家长,这真的是唯一的方法吗 以下是我的映射供参考: 父映射: HasMany(x => x.Children).KeyColumn("Parent

我正试图用列表子实体保存(插入)父实体。两个实体都使用Guid作为主键。密钥不可为null,并且数据库中没有设置密钥关系

保存不起作用,抛出一个异常,声称我正在尝试将null保存到子表的父外键中

我希望nhibernate为父对象创建一个键,并让它的子对象知道它。这是NHibernate的限制还是使用GUID作为主键的限制

这意味着你必须手动设置家长,这真的是唯一的方法吗

以下是我的映射供参考:

父映射:

HasMany(x => x.Children).KeyColumn("ParentKey").Inverse().Cascade.All();
子映射:

 References(x => x.Parent).Not.Nullable().Column("ParentKey");

NHibernate不是魔法。这只是一个ORM,如果您的孩子没有将他们的引用设置为父对象,为什么它会认为,因为父对象有一个子对象列表,所以子对象的引用反过来应该是对父对象的引用

我相信您已经回答了自己的问题,当您声明子实体没有填充其父属性时(这意味着它为null,这意味着NHibernate将尝试在子表中为父id保存一个“null”值)

如果要在不使用NHibernate的情况下使用这些对象,则在添加子实体时需要在子实体上设置父引用是有意义的

编辑:这适用于您在映射上指定了“逆”的情况。如果要删除对'reverse'的调用,它应该按照您希望的方式工作,因为reverse声明另一端(子实体)负责跟踪关系。这意味着您需要手动设置父对象对子对象的引用

但是,删除Inverse语句将导致保存子(ren),保存父(ren),然后更新子(ren)的父(ren)id。由于父id上有一个null约束,这意味着它仍然无法工作,因为它最初会插入父id为null的子项

这两种解决方案要么删除此约束,要么只向父级添加一个名为AddChild:

public void AddChild(Child childObj)
{
    childObj.Parent = this;
    Children.Add(childObj);
}
public void RemoveChild(Child childObj)
{
    if (Children.Contains(childObj))
    {
        Child.Parent = null;
        Children.Remove(childObj);
    }
}
添加另一个名为RemoveChild:

public void AddChild(Child childObj)
{
    childObj.Parent = this;
    Children.Add(childObj);
}
public void RemoveChild(Child childObj)
{
    if (Children.Contains(childObj))
    {
        Child.Parent = null;
        Children.Remove(childObj);
    }
}

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

确保我不希望在保存之前的运行时出现引用(可能我的问题有误导性,我会编辑它)-我希望Nhibernate知道父项和子项都是新的,并且知道如何使用适当的键来保持它们…太多的问题了?只是为了解释更多的映射和约束,请检查此链接