简体   繁体   中英

NHibernate many-to-many mapping

I am having an issue with many-to-many mapping using NHibernate. Basically I have 2 classes in my object model (Scenario and Skill) mapping to three tables in my database (Scenario, Skill and ScenarioSkill). The ScenarioSkills table just holds the IDs of the SKill and Scenario table (SkillID, ScenarioID).

In the object model a Scenario has a couple of general properties and a list of associated skills (IList) that is obtained from the ScenarioSkills table. There is no associated IList of Scenarios for the Skill object.

The mapping from Scenario and Skill to ScenarioSkill is a many-to-many relationship:

Scenario * --- * ScenarioSkill * --- * Skill

I have mapped out the lists as bags as I believe this is the best option to use from what I have read. The mappings are as follows:

Within the Scenario class

<bag name="Skills" table="ScenarioSkills">
  <key column="ScenarioID" foreign-key="FK_ScenarioSkill_ScenarioID"/>
  <many-to-many class="Domain.Skill, Domain" column="SkillID" />
</bag>

And within the Skill class

<bag name="Scenarios" table="ScenarioSkills" inverse="true" access="noop" cascade="all">
  <key column="SkillID" foreign-key="FK_ScenarioSkill_SkillID" />
  <many-to-many class="Domain.Scenario, Domain" column="ScenarioID" />
</bag>

Everything works fine, except when I try to delete a skill, it cannot do so as there is a reference constraint on the SkillID column of the ScenarioSkill table. Can anyone help me?

I am using NHibernate 2 on an C# asp.net 3.5 web application solution.

Unless I'm reading the question incorrectly you need to delete the related ScenarioSkills before you delete a Skill or a Scenario. It's pretty straighforward, you just need a custom method to delete the relates ScenarioSkill objects before you delete the parent record.

Do you want it to delete automatically though?

You'll want to set cascade="all-delete-orphan" on Skills many-to-many linking to ScenarioSkills. Just like it sounds, it will delete the orphaned records and keep that error from popping up.

As a side note, many-to-many's should be used with care. Most many-to-manys contain other information in the relationship and are better mapped as a set of one-to-manys.

Bit late on the final reply here but this the the mapping I ended up successfully implementing.

In Scenario

<bag name="skills" access="field" schema="OSM" table="ScenarioSkill" cascade="none">
  <key column="ScenarioID"
       foreign-key="FK_ScenarioSkill_Scenario" />

  <!-- Skills can be soft-deleted (groan), so ignore them if they don't 'exist' anymore. -->
  <many-to-many column="SkillID"
                class="DomainModel.Skill, DomainModel"
                foreign-key="FK_ScenarioSkill_Skill"
                where="IsDeleted = 0"/>
</bag>

In Skill

    <!-- inverse end of scenarios -->
<bag name="scenarios" access="field" inverse="true" schema="OSM" table="ScenarioSkill" cascade="none">
  <key column="SkillID"
       foreign-key="FK_ScenarioSkill_Skill" />
  <many-to-many column="ScenarioID"
                class="Scenario"
                foreign-key="FK_ScenarioSkill_Scenario" />
</bag>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM