我无法理解我应该与NH实施有序的儿童关系。
在代码世界中,我有:
class Parent
{
public Guid Id;
public IList<Child> Children;
}
class Child
{
public Guid Id;
public Parent Parent;
}
Parent
有一个包含订单的Child[ren]
列表。实际上,Children
集合将包含将由其他代码强制执行的唯一Child
(即,永远不可能将相同的子项添加到集合中两次 - 所以我不会真的护理如果NH集合强制执行此操作
我应该如何实现这两个类的映射?
根据我的理解:
Bags
没有订单,所以我不想要这个Sets
没有订单,但我可以使用order-by
来做一些sql命令,但是我的订单是什么?我不能依赖顺序ID。所以我不想要这个?Lists
是一个无重复的集合,其中唯一键是PK
和index
列,所以我确实想要这个吗?所以,使用list
,我有以下内容:
<list cascade="all-delete-orphan" inverse="true" name="Children">
<key>
<column name="Parent_id" />
</key>
<index>
<column name="SortOrder" />
</index>
<one-to-many class="Child" />
</list>
当我插入一个孩子的父母时,我看到以下SQL:
Insert into Child (id, Parent_id) values (@p0, @p1)
即,为什么不插入SortOrder?
如果我执行SchemaExport
,则会在子表上创建SortOrder列。
:(
如果我在关系上设置Inverse="false"
,我会看到与上面相同的SQL,然后是:
UPDATE "Child" SET Parent_id = @p0, SortOrder = @p1 WHERE Id = @p2
为什么它仍然是INSERT
带有inverse="false"
的Parent_id,为什么不将SortOrder与inverse="true"
一起插入?
我接近这完全错了吗?
假设这是有效的,如果我这样做也是如此:
parentInstance.Children.Remove(parentInstance.Children[0]);
保存父级并重新加载,list
在位置0中将为空,而不是将其余部分移动?
由于
答案 0 :(得分:1)
Inverse=true
表示NHib不会尝试保存实际的集合。但是,它仍然级联通过集合到包含的实体上的保存操作,其中包括持久的瞬态实例。这就是为什么你得到一个没有SortOrder的插入的原因 - NHib会持久化你的瞬态Child
对象。
有a similar question解决方案涉及转移到<bag>
映射,但这会失去<list>
的排序质量。
现在我使用<list>
之前使用<many-to-many>
映射,并且它运行良好。有两个SQL插入调用 - 一个包含子实体的表,另一个包含到链接表。我怀疑在你的情况下,即使两个电话都在同一张桌子上,NHib仍然采用相同的策略。
最后,如果删除索引0处的项目,那么最终会得到一个空值。
总的来说,我建议:1)转移到集合的<bag>
映射,并维护排序顺序的特定属性;或者2)转移到集合中的<many-to-many>
映射。