2009-12-02 80 views
1

我很难让我的头部周围的方式,我应该与NH实施有序的儿童关系。在NHibernate中存储一个订购的儿童收藏

在代码的世界里,我有:

class Parent 
{ 
    public Guid Id; 
    public IList<Child> Children; 
} 

class Child 
{ 
    public Guid Id; 
    public Parent Parent; 
} 

一个ParentChild[ren]与订单列表。在现实中,Children集合将包含独特的Child S的将被其他代码执行(即,它会永远不可能添加相同的孩子收集两次 - 所以我不真正关心如果NH集合强制执行此)

我应该如何实现两个类的映射?

从我的理解:

  • Bags没有订单,所以我不希望这
  • Sets没有秩序,但我可以用order-by做一些SQL排序,但我订的是什么?我不能依靠顺序ID。所以我不想要这个?
  • Lists是一个免副本的集合,其中unique-key是PKindex列,所以我确实需要这个?

所以,使用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列在Child表上创建。

:(

如果我的关系设置Inverse="false",我看到相同的SQL同上,依次为:

UPDATE "Child" SET Parent_id = @p0, SortOrder = @p1 WHERE Id = @p2 

为何仍INSERT的PARENT_ID与inverse="false"为什么不它与inverse="true"插入SortOrder的?

上午我处理这个完全错误的?

是否也是如此,假设这是工作,如果我做的事:

parentInstance.Children.Remove(parentInstance.Children[0]); 

拯救父母和重新加载它,那list将有一个空位置0,而不是洗牌剩下的呢?

感谢

回答

1

Inverse=true意味着NHib不会尝试保存真正的集合。然而,它仍将级联通过收集到保存的实体上的保存操作,其中包括保留瞬态实例。这就是为什么你会得到一个没有SortOrder的插入物--NHib会持续你的瞬态物体Child

a similar question其中解决方案涉及到<bag>映射,但失去了<list>具有的订购质量。

现在,我已经有<many-to-many>映射前使用的<list>,有它的工作很大。有两个SQL插入调用 - 一个包含子实体,另一个包含链接表。我怀疑,在你的情况下,即使两个电话都在同一张表上,NHib仍然使用相同的策略。

最后,如果您删除索引0处的项目,则最终会出现空值。所以总的来说,我建议:1)移动到<bag>映射您的收藏,并维护一个特定的属性排序顺序;或者2)移至集合中的<many-to-many>映射。