开发者

Storing an ordered child collection in NHibernate

开发者 https://www.devze.com 2022-12-13 14:03 出处:网络
I\'m having trouble getting my head around the way I s开发者_运维技巧hould implement an ordered child relationship with NH.

I'm having trouble getting my head around the way I s开发者_运维技巧hould implement an ordered child relationship with NH.

In the code world, I have:

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

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

A Parent has a list of Child[ren] with an order. In reality, the Children collection will contain unique Childs which will be enforced by other code (i.e. it will never be possible to add the same child to the collection twice - so i dont really care if the NH collection enforces this)

How should I implement the mappings for both classes?

From my understanding:

  • Bags have no order, so i dont want this
  • Sets have no order, but i could use order-by to do some sql ordering, but what do i order by? I can't rely on a sequential ID. so i dont want this?
  • Lists are a duplicate-free collection, where the unique-key is the PK and the index column, so i do want this?

So, using a list, i have the following:

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

When I insert a parent which a child on it, i see the following SQL:

Insert into Child (id, Parent_id) values (@p0, @p1)

I.e, why doesn't it insert the SortOrder?

If I do a SchemaExport the SortOrder column is created on the Child table.

:(

If I set Inverse="false" on the relationship, i see the same SQL as above, followed by:

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

Why does it still INSERT the Parent_id with inverse="false" and why doesn't it insert the SortOrder with inverse="true"?

Am I approaching this totally wrong?

Is it also true that assuming this was working, if I were to do:

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

save the parent and reload it, that the list would have a null in position 0, instead of shuffling the rest up?

Thanks


Inverse=true means that NHib will not try to save the actual collection. It will however still cascade the save operation through the collection onto the contained entities, which includes persisting transient instances. This is why you get an insert with no SortOrder - NHib is persisting your transient Child object.

There was a similar question where the solution involved moving to <bag> mappings, but that loses the ordering qualities that <list> has.

Now I've used a <list> before with a <many-to-many> mapping, and there it worked great. There were two SQL insert calls - one to the table containing the child entity and the other to the linking table. I suspect that in your '' case, NHib is still applying the same strategy even though both calls are to the same table.

And finally, if you remove the item at index 0 then you end up with a null value.

So overall, I'd suggest either: 1) move to a <bag> mapping for your collection, and maintaining a specific property for sort order; or 2) move to a <many-to-many> mapping inside your collection.

0

精彩评论

暂无评论...
验证码 换一张
取 消