NHibernate:级联保存到子级不会插入

NHibernate:级联保存到子级不会插入,nhibernate,fluent-nhibernate,Nhibernate,Fluent Nhibernate,我有这样的双向关联: public class Parent { public int ParentId {get; set;} ...other properties public IEnumerable<Child> Children {get; set;} } public class Child { public int ChildId {get; set;} ...other properties public Parent Parent {get

我有这样的双向关联:

public class Parent
{
  public int ParentId {get; set;}
  ...other properties
  public IEnumerable<Child> Children {get; set;}
}

public class Child
{
  public int ChildId {get; set;}
  ...other properties
  public Parent Parent {get; set;}
}
Parent parent = new Parent{ ..set some properties... };
parent.Children = new[] { new Child{ ..set some properties.. };
session.Save(parent);
子映射

当我执行这样的代码时:

public class Parent
{
  public int ParentId {get; set;}
  ...other properties
  public IEnumerable<Child> Children {get; set;}
}

public class Child
{
  public int ChildId {get; set;}
  ...other properties
  public Parent Parent {get; set;}
}
Parent parent = new Parent{ ..set some properties... };
parent.Children = new[] { new Child{ ..set some properties.. };
session.Save(parent);
我得到外键约束冲突,因为当NHibernate尝试插入子记录时,它没有将子记录的
PARENT\u ID
列设置为新ID


显然,我已经请求在映射中为
父级
进行级联。NHibernate正在尝试保存孩子,但为什么没有设置ID?

您需要进行两项更改

  • HasMany(x=>x.Children)
    上需要
    .Inverse()
    。有关更多信息,请参阅
  • 您还需要添加
    child.Parent=Parent到保存实体的代码
  • 在您的案例中,这两种关系相互冲突
    parent.Children
    包含
    child
    ,这意味着NHibernate应将
    child.parent\u ID
    保留为父ID,但
    child.parent
    为null,这意味着NHibernate应将
    child.parent\u ID
    保留为null。显然,孩子的父母赢了。事实上,更有可能的是他们都赢了。NHibernate可能正在执行两个类似的查询

    /* This is what child.Parent says we should save.
       This query will fail because PARENT_ID is NOT NULL. */
    insert into Child (CHILD_ID, PARENT_ID) values (@childId, null);
    
    /* This is what parent.Children says we should save. */
    update Child set PARENT_ID = @parentId where CHILD_ID = @childId;
    
    如果您进行我上面建议的两项更改,NHibernate将能够正确地保存此内容,如下所示:

    insert into Child (CHILD_ID, PARENT_ID) values (@childId, @parentId);
    

    所以我需要在保存之前设置关系的两侧?您至少需要设置关系的非反向一侧:
    child.Parent
    。如果
    parent.Children
    相反,则将
    child
    添加到
    parent.Children
    是可选的,但为了保持模型的一致性,这是一个好主意。另一种方法是完全去掉
    child.Parent
    属性(不能使
    多对一
    反转),并将
    HasMany(x=>x.Children)
    保留为非反转。无论选择哪种路由,都必须设置非反向关系的值。如何删除child.Parent属性并在hibernate.config中进行映射?