NHibernate:级联保存给孩子不会插入

Dav*_*vid 3 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; set;}
}
Run Code Online (Sandbox Code Playgroud)

流畅的映射如下:

父映射

Id(x => x.ParentId, "PARENT_ID").GeneratedBy.Identity();
.. other mappings
HasMany(x => x.Children).Cascade.All().KeyColumn("PARENT_ID");
Run Code Online (Sandbox Code Playgroud)

儿童映射

Id(x => x.ChildId, "CHILD_ID").GeneratedBy.Identity();
.. other mappings
References(x => x.Parent).Column("PARENT_ID").Cascade.None();
Run Code Online (Sandbox Code Playgroud)

当我执行这样的代码时:

Parent parent = new Parent{ ..set some properties... };
parent.Children = new[] { new Child{ ..set some properties.. };
session.Save(parent);
Run Code Online (Sandbox Code Playgroud)

我收到外键约束违规,因为NHibernate PARENT_ID在尝试插入子项时没有将子记录的列设置为新ID.

显然我已经请求在映射中级联Parent.NHibernate试图拯救孩子,但为什么ID没有被设置?

Dan*_*ing 7

您需要进行两项更改.

  1. 你需要.Inverse()HasMany(x => x.Children).有关详细信息,请参阅我的答案解释逆.
  2. 您还需要添加child.Parent = parent;保存实体的代码.

在您的情况下,这两种关系彼此冲突. parent.Children包含child,这意味着NHibernate应该Child.PARENT_ID作为父ID继承,但是child.Parent为null,这意味着NHibernate应该保持Child.PARENT_ID为null.显然child.Parent赢了.实际上,更有可能的是他们都赢了.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;
Run Code Online (Sandbox Code Playgroud)

如果您进行上面我推荐的两项更改,NHibernate将能够正确保存,如下所示:

insert into Child (CHILD_ID, PARENT_ID) values (@childId, @parentId);
Run Code Online (Sandbox Code Playgroud)