我有这样的双向关联:
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;}
}
流畅的映射如下:
父映射
Id(x => x.ParentId, "PARENT_ID").GeneratedBy.Identity();
.. other mappings
HasMany(x => x.Children).Cascade.All().KeyColumn("PARENT_ID");
子映射
Id(x => x.ChildId, "CHILD_ID").GeneratedBy.Identity();
.. other mappings
References(x => x.Parent).Column("PARENT_ID").Cascade.None();
当我执行这样的代码时:
Parent parent = new Parent{ ..set some properties... };
parent.Children = new[] { new Child{ ..set some properties.. };
session.Save(parent);
我收到外键约束违规,因为NHibernate在尝试插入子项时没有将子记录的PARENT_ID
列设置为新ID。
显然,我已经请求Parent
的映射级联。 NHibernate试图拯救孩子,但为什么ID没有被设置?
答案 0 :(得分:7)
您需要进行两项更改。
.Inverse()
上需要HasMany(x => x.Children)
。有关详细信息,请参阅my answer explaining inverse。child.Parent = parent;
添加到保存实体的代码中。在您的情况下,这两种关系彼此冲突。 parent.Children
包含child
,这意味着NHibernate应该Child.PARENT_ID
作为父ID,但child.Parent
为空,这意味着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);