0

i'm working with legacy code(so i'd like to change it as little as possible), and i'm having a little trouble with a many to many relationship here.

Here's what i have:

public class Feature {
   List<Profile> Profiles{get;set;}
}

public class Profile{
   List<FeatureProfile> Features{get;set;}
}

public class FeatureProfile {
   Feature Feat {get;set;}
   Profile Profile {get;set;}
}

and their mapping is like this:

mapper.Class<Feature>(m=>
    m.Bag(x => x.Profiles, bagMap =>
                    {
                        bagMap.Table("FeatureProfile");
                        bagMap.Key(key=>key.Column("FeatureId"));
                        bagMap.Cascade(Cascade.All | Cascade.DeleteOrphans);
                    },map=>map.ManyToMany(manyToMany=>manyToMany.Column("ProfileId")))
);


mapper.Class<Profile>(m=>
    m.Bag(x => x.Features, bagMap =>
                    {
                        bagMap.Key(key=>key.Column("ProfileId"));
                        bagMap.Inverse(true);
                        bagMap.Cascade(Cascade.All | Cascade.DeleteOrphans);
                   })
);

mapper.Class<FeatureProfile>(m=> {
    m.ManyToOne(x => x.Profile, x => x.Column("ProfileId"));
    m.ManyToOne(x => x.Feat, x => x.Column("FeatureId"))
});

What I need is: When I delete a Feature, it's FeatureProfile's get deleted too. Note that I think this probably worked in NHibernate 2.x

Tejo
  • 1,268
  • 11
  • 18

1 Answers1

1

My experience is more with XML mapping, but I would say that the below rows could help you anyway. NHibernate provides direct mapping for m:n reletaions (with Pair-table, as in example above). You can totally remove the object FeatureProfile. The relation will be mapped implicitly, and the same will apply when deleting any of both ends (Profile or Feature)

<class name="Feature"...>
... 
<bag name="Profiles" lazy="true" 
    table="FeatureProfile" cascade="none" >
  <key column="FeatureId" />
  <many-to-many class="Profile" column="ProfileId" />
</bag>
...

<class name="Profile"...>
... 
<bag name="Features" lazy="true" 
    table="FeatureProfile" cascade="none" >
  <key column="ProfileId" />
  <many-to-many class="Feature" column="FeatureId" />
</bag>
...

And in this case, NHibernate has no other way, when deleting Feature, then to delete Pair-table records as well (cannot/should not leave DB inconsistent).

EDITED: cascade for a bag should be none in this case. delete-orphan would cause really dangerous deletion: not only the pairs but also the ends of that relation.

EDIT BY OP: Here's what we'd have using Mapping by Code:

mapper.Class<Profile>(m =>
{
    m.Bag(x => x.Features, bagMap =>
    {
        bagMap.Table("FeatureProfile");
        bagMap.Key(key=>key.Column("ProfileId"));
        bagMap.Lazy(CollectionLazy.Lazy)
        bagMap.Inverse(false);
        bagMap.Cascade(Cascade.None);
    },map=>map.ManyToMany(manyToMany=>manyToMany.Column("FeatureId")))
}

mapper.Class<Feature>(m =>
{
    m.Bag(x => x.Profiles, bagMap =>
    {
        bagMap.Table("FeatureProfile");
        bagMap.Key(key=>key.Column("FeatureId"));
        bagMap.Lazy(CollectionLazy.Lazy)
        bagMap.Inverse(false);
        bagMap.Cascade(Cascade.None);
    },map=>map.ManyToMany(manyToMany=>manyToMany.Column("ProfileId")))
}); 
Tejo
  • 1,268
  • 11
  • 18
Radim Köhler
  • 122,561
  • 47
  • 239
  • 335
  • Thanks for the reply, and sorry for taking so long to answer, I posted this right before leaving work for the weekend. I changed my code to generate exactly this, but it still didn't work :( any other ideas? – Tejo Oct 08 '12 at 12:19
  • Hi. I just retested the above solution. In fact there was a bug (fixed now), because the cascade should be "none" in this case. Any other setting would not effect the pair table but the end of the relation. So, this type of mapping should work, when one of the ends is removed, all pairs are deleted as well. Is it working for you? – Radim Köhler Oct 08 '12 at 14:29
  • Now it is, Thanks a lot for your help. Can I change your answer to show the equivalent code using Mapping by code? – Tejo Oct 09 '12 at 01:53
  • Yes, definitely, adjust it to show the real working result. Glad it works – Radim Köhler Oct 09 '12 at 04:13