views:

20

answers:

2

I have the following entities:

namespace NhLists {
  public class Lesson {
    public virtual int Id { get; set; }
    public virtual string Title { get; set; }
  }
  public class Module {
    public virtual int Id { get; set; }
    public virtual IList<Lesson> Lessons { get; set; }
    public Module() {
      Lessons = new List<Lesson>();
    }
  }
}

And the following mappings:

<class name="Module" table="Modules">
  <id name="Id">
    <generator class="identity"/>
  </id>
  <list name="Lessons" table="ModuleToLesson"
      cascade="save-update">
    <key column="moduleId"/>
    <index column="position"/>
    <many-to-many 
      column="lessonId" 
      class="NhLists.Lesson, NhLists"/>
  </list>
</class>
<class name="Lesson" table="Lessons">
  <id name="Id">
    <generator class="identity"/>
  </id>
  <property name="Title">
    <column name="Title" length="16" not-null="true" />
  </property>
</class>

When I delete a lesson by session.Delete(lesson), is there anyway I can have NHibernate automatically update the association in Module.Lessons to remove the entry from the set? Or am I forced to go through all Modules and look for the lesson and remove that by hand?

Edit: Fixed ICollection and in mappings to IList<> and like I ment and tested it.

A: 

Turns out that if we do not need IList semantics and can make do with ICollection the update problem can be solved by adding a reference back from Lesson to Module, such as:

public class Lesson {
  ...
  protected virtual ICollection<Module> InModules { get; set; }
  ...
}

And to the mapping files add:

<class name="Lesson" table="Lessons">
  ...
  <set name="InModules" table="ModuleToLesson">
    <key column="lessonId"/>
    <many-to-many column="moduleId" class="NhLists.Module, NhLists"/>
  </set>
</class>

Then a Lesson deleted is also removed from the collection in Module automatically. This also works for lists but the list index is not properly updated and causes "holes" in the list.

kaa
+1  A: 

You have false idea. If you want to delete the Lesson object from Module you do that manually. NHibernate just tracks such your action and when session.Commit() is called then the reference between Module and Lesson is deleted in the database.

Calling session.Delete(lesson) deletes the lesson object from database (if foreign keys are set properly then reference between Module and Lesson is deleted of course but it is not responsibility for NHibernate).

In conclusion, it is not possible to delete the lesson object from the Module.Lessons list automatically by calling session.Delete(lesson). NHibernate does not track such entity references.

Petr Kozelek
Ok, so what tricked me was that it's actually the database that clears the reference (by way of the FK) and not NHibernate? That seems a reasonable explanation to the behavour I'm seeing.
kaa