Using AsList() returns null objects depending on the SortOrder
In our project, we are using tabs. These tabs have content. Multiple content objects can be on a tab. So we could have a 'car' tab, and that car tab may display a sedan content object, a suv content object and a truck content object. The user could also specify that it contains more or less of these objects and order them however they want. It is important for us to maintain the order of these content objects to user specification.
Here are my mappings :
On the Tab mapping :
HasManyToMany(t => t.ContentObjects)
.Table("TabContentObjects")
.ParentKeyColumn("TabID")
.ChildKeyColumn("ContentObjectID")
.AsList(index => index.Column("SortOrder"));
On the ContentObject mapping :
HasManyToMany(c => c.Tabs)
.Table("TabContentObjects")
.ParentKeyColumn("ContentObjectID")
.ChildKeyColumn("TabID")
.Cascade.SaveUpdate()
.AsList(index => index.Column("SortOrder"));
The association table is :
TabContentObjectId
TabId
ContentObjectId
SortOrder int not null
I am able to add a content object, re-order a content object within a tab, and all is well. nHibernate is adding / updating the SortOrder appropriately. The problem comes when I am trying to delete a content object. When I go to delete the tabs from this contentObject, contentObject.Tabs looks odd.
Here is the code I use to delete the tabs :
//Need to remove each through the contentObject since it is parent
foreach (Tab tab in deleteContentObject.Tabs)
{
tab.RemoveContentObject(deleteContentObject);
}
//in Tab class
public virtual void RemoveContentObject(TabContentObject item)
{
if (ContentObjects == null) ContentObjects = new List<TabContentObject>();
ContentObjects.Remove(item);
}
If it is the ONLY, or the first (SortOrder = 0) contentObject within a tab, I can delete. If it is the second content object, contentObject.Tabs look like [0] [null] [1] [Tab]. If it is the fourth contentObject on the tab, contentObject.Tabs looks like [0] [null] [1] [null] [2] [null] [3][Tab].
So, depending on what the SortOrder column is in the association table, I seem to have many null references returned, and therefore cannot delete due to a null reference. I cannot figure out why these nulls are being returned. Any help would be appreciated.
Support Staff 2 Posted by Paul Batum on 25 Jul, 2010 08:53 AM
You might be best off asking for help on the nhibernate
users<http://groups.google.com/group/nhusers/> mailing
list as this is really a question that is specifically about NHibernate's
behavior. If they ask you for an xml version of your mappings, see here:
http://wiki.fluentnhibernate.org/Fluent_configuration#Exporting_mappings
3 Posted by jason.sperko on 29 Jul, 2010 09:37 PM
Thanks for the info Paul. I guess, in general, is it supported, to map a many-to-many relationship in this fashion?
Say a Product table, a Order table, and then a ProductOrder table, where the ProductOrder table contains the ProductId, the OrderId, and some SortOrder, where we could sort the Products in any order we wanted to, but have it come back how we sorted.
Am I correct in saying the mapping would look as it does in my example?
Support Staff 4 Posted by Paul Batum on 30 Jul, 2010 04:46 PM
I think its supported but I haven't done it and so I can't really help much.
This is just the sort of question I'm suggesting you go to the NH list for.
When it comes to what NH can and cannot do, the list is where the experts
are.
Support Staff 5 Posted by James Gregory on 31 Jul, 2010 06:40 AM
I second Paul's suggestion to ask at the NH users list; but from what I've
used of lists, your situation sounds perfectly normal. When you're using a
collection with an explicit order (an index, such as a list), NHibernate
expects the number sequence to be contiguous; if it encounters any gaps in
the sequence they get filled in with nulls.
You either need to update the order of items after the one you're deleting
to compensate for the gap, or not used a strict ordered sequence; instead
you could just use a bag with an order by.
6 Posted by jason.sperko on 02 Aug, 2010 05:19 PM
I have resolved this with the following :
Tab Map :
Content Object Map :
So I only needed the AsList on one map. I also made the Tab the parent.
To remove the tabs :
With this configuration, a tab's content is ordered the way we would like. Sorting is automatically updated by nHibernate on updates, add, deletes.