Fluent nhibernate 将对象添加到集合的NHibernate持久化顺序

Fluent nhibernate 将对象添加到集合的NHibernate持久化顺序,fluent-nhibernate,Fluent Nhibernate,我可能犯了一个新手的错误,但我不知道该怎么做。我有两个实体-父实体和子实体,其中一个父实体可以有多个子实体ren。问题似乎是,当我向父级添加新的子级时,父级无法级联保存子级,因为子级实例还没有ID。另一方面,孩子不能自己坚持,所以他没有办法得到一个ID 我的映射: public ParentMap() { // ID and other properties HasMany(p => p.Children).Cascade.AllDeleteOrphan().Not.L

我可能犯了一个新手的错误,但我不知道该怎么做。我有两个实体-
父实体
子实体
,其中一个
父实体
可以有多个
子实体
ren。问题似乎是,当我向父级添加新的子级时,父级无法级联保存子级,因为子级实例还没有ID。另一方面,孩子不能自己坚持,所以他没有办法得到一个ID

我的映射:

public ParentMap()
{ 
    // ID and other properties

    HasMany(p => p.Children).Cascade.AllDeleteOrphan().Not.LazyLoad();
}

public ChildMap()
{
    // ID and other properties

    References(c => c.Parent);
}
现在,我的数据库中可能已经有一个父记录,我想将一个子记录添加到它的子记录集合中。为此,我创建了
Child
类的一个新实例,将该子类添加到父类的
Children
属性中(类型为
IList
)。我还获取父记录,并将childs
parent
属性设置为父实体

当我试图保存它时,无论我尝试保存的顺序如何,都会出现错误

使用
Save(p)
,保存父记录并希望子记录将以级联方式保存,我得到以下错误:

无法将值NULL插入表“dbo.Children”的列“ChildID”;列不允许空值。插入失败。声明已终止

如果我尝试另一种方法,即先保存子项,然后将其添加到父项并保存父项,则会出现以下错误:

Application.Domain.Entities.Child条目中的null id(发生异常后不要刷新会话)

我应该按什么顺序调用
parent.Children.Add(child)
child.parent=parent
session.Save(parent)
、和
session.Save(child)
?我的映射配置中是否缺少某些内容

更新:我添加了
.Inverse()
,并尝试了以下操作但未成功:

// First of the above errors
session.Save(child);
child.Parent = parent;
parent.Children.Add(child);
session.Save(parent);

// Second of the above errors
child.Parent = parent;
parent.Children.Add(child);
session.Save(child);
session.Save(parent);

// Second of the above errors
child.Parent = parent;
parent.Children.Add(child);
session.Save(parent);

// Second of the above errors
child.Parent = parent;
parent.Children.Add(child);
session.Save(child);

在家长一侧,将您的关系标记为反向。这将说明NHibernate儿童方管理关系:

HasMany(p => p.Children).Cascade.AllDeleteOrphan().Not.LazyLoad().Inverse();
这迫使您手动设置
child.Parent=Parent
,但您仍然在这样做,因此我相信这不是问题

默认情况下,NHibernate假定父级有责任为子级设置外键。操作的逻辑顺序是这样的:

  • 要保存的父对象
  • 由于层叠,孩子们被保存了下来——我们还没有父母ID(至少我们没有,我不知道为什么我们也知道这样做)
  • 在父项的外键中插入子项时带有
    null
  • 然后成功插入父对象,并获取其ID
  • 子项更新了父项的外键
  • 在您的第一个场景中,它在第3位失败,因为您没有可为空的外键列,并且NHibernate不够聪明,无法找到任何解决方案


    设置
    Inverse()。在本例中保存时,正如预期的那样,只有插入,并且没有尝试在外键中设置
    null

    结果表明问题根本不在于NHibernate,而在于我的数据库配置-我忘记了配置
    子表的ID列。一旦我指定了ID列,一切都按预期进行:不需要
    .Inverse()
    ,我可以只保存
    父项
    ,而
    子项
    则保存在cascade上

    我缺少
    Cascade.All()
    引用。我们不应该把
    Inverse()
    放在
    HasMany上:

    public ParentMap()
    { 
        // ID and other properties
    
        HasMany(p => p.Children).Cascade.AllDeleteOrphan().Not.LazyLoad();
    }
    
    public ChildMap()
    {
        // ID and other properties
    
        References(c => c.Parent).Cascade.All();
    }
    
    使用您建议的
    .Inverse()
    ,我仍然会得到完全相同的错误。