Recursive tree NHibernate with databinding in Winforms combobox
After a couple of days searching and trying things I need to ask the question, because I'm out of options. The scenario is simple: a recursive category tree. The tree is fetched from a single table and has to be bound to a combobox in a Winforms app.
The mapping in NHibernate is not the problem; the tree is correctly mapped. Also the binding to the combobox works. The problem is when I want to save the category, I get a Parameter index out of range error and that is understandable, because as you can see from the listings below, NH is using both the property and the foreign key in the many-to-one mapping to update the database, and they both refer to the same column.
The problem is that I need the property ParentGroupId for the databinding of the combobox, and I also need the foreign key in the many-to-one mapping. Has anyone encountered a similar situation? I think I have tried almost any possible scenario but so far no luck.....
The class:
public class ProductGroup : EntityBindable
{
public virtual string GroupName开发者_运维问答 { get; set; }
public virtual ProductGroup _parentGroup { get; set; }
public virtual IList<ProductGroup> _subGroups { get; set; }
public virtual int ParentGroupId { get; set; }
}
The mapping:
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="Brickx.Model" namespace="Brickx.Model">
<class name="ProductGroup">
<id name="Id" type="int" unsaved-value="0">
<generator class="hilo">
</generator>
</id>
<property name="GroupName" type="string" length="50" />
<property name="ParentGroupId" type="Int32" />
<many-to-one name="ParentGroup"
column="ParentGroupId"
class="ProductGroup" />
<bag name="SubGroups" cascade="all, delete-orphan">
<key column="ParentGroupId" />
<one-to-many class="ProductGroup" />
</bag>
</class>
</hibernate-mapping>
You have two options:
1) Remove ParentGroupId mapping from hbm file. This way NHibernate would not even now about this property and would not cause you any problems. Bind your combobox to group.ParentGroup.Id. If this is not possible you can simply implement this property yourself:
class ProductGroup {
...
public virtual int ParentGroupId {
get {
if (_parentGroup != null) {
return _parentGroup.Id;
}
return 0;
}
}
...
}
2) Map 'ParentGroupId' with update and insert set to false:
<property name="ParentGroupId" type="Int32" update="false" insert="false"/>
Note that your mapping may be incorrect and you may need to add inverse attribute on your 'bag'. This way you tell NHibernate to persist 'many-to-one' side of bidirectional association first. Try setting it like this:
<bag name="SubGroups" cascade="all, delete-orphan" inverse="true" >
精彩评论