Storing an ordered child collection in NHibernate
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 Child
s 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 thisSets
have no order, but i could useorder-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 thePK
and theindex
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.
精彩评论