views:

30

answers:

1

I'm trying to use NHibernate to map a table per subclass inheritance structure that looks something like this:

public class BaseClass
{
    public virtual IColllection<BaseClassCollection> Collection { get; set; }
}

public class ChildClass : BaseClass
{
    public new virtual ICollection<ChildClassCollection> Collection { get; set; }
}

I get the following error when I try to get a ChildClass from the session:

"Unable to cast object of type 'NHibernate.Collection.Generic.PersistentGenericBag1[BaseClassCollection]' to type 'System.Collections.Generic.ICollection1[ChildClassCollection]'."

Here's my mapping file:

<class name="BaseClass" table="BaseClassTable">
  <bag name="Collection">
    <key>
      <column name="BaseClassCollectionId" />
    </key>
    <one-to-many class="BaseClassCollection" />
  </bag>
  <joined-subclass name="ChildClass" table="ChildClassTable">
    <key>
      <column name="BaseClassId" />
    </key>
    <bag name="Collection">
      <key>
        <column name="ChildClassCollectionId" />
      </key>
      <one-to-many class="ChildClassCollection" />
  </bag>
</class>

I need some way of overriding the type of the Collection property in the base class when I map the child class. Is this possible with NHibernate?

A: 

I think the only way you'll get this to work is if you do something along these lines:

public class BaseClass<TChild> where TChild : BaseClassCollection {
    public virtual ICollection<TChild> Collection { get; set; }
}

public class ChildClass<TChild> : BaseClass<TChild> where TChild : ChildClassCollection {
    public override ICollection<TChild> Collection { get; set; }
}

public class BaseClassCollection { }
public class ChildClassCollection : BaseClassCollection { }

The issue is that the new keyword breaks inheritence, and then your mapping is relying on that inheritence. You really should avoid using new anywhere because its not a great idea; take NHibernate out of the mix, and you'll get different behaviors depending on how you cast your class; cast it as BaseClass and youll get something totally different than if you cast it as ChildClass.

If that's not the answer you're looking for I appologize, but I don't think it's possible to get it working if you need to use the new keyword.

HTH Andy

Andy