4

I have a bidirectional association like this:

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;}
}

The fluent mappings are as follows:

Parent mapping

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

Child mapping

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

When I execute code like this:

Parent parent = new Parent{ ..set some properties... };
parent.Children = new[] { new Child{ ..set some properties.. };
session.Save(parent);

I get a foreign key constraint violation because NHibernate is not setting the PARENT_ID column of the child record to the new ID when it attempts to insert the child.

Clearly I have requested cascading in the mapping for Parent. NHibernate is trying to save the child, but why is the ID not being set?

4

1 回答 1

7

您需要进行两项更改。

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

在您的情况下,这两种关系相互冲突。 parent.Childrencontains 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;

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

insert into Child (CHILD_ID, PARENT_ID) values (@childId, @parentId);
于 2013-08-22T17:36:56.207 回答