sisdog
sisdog

Reputation: 2719

NHibernate Discrimator

I have a table called DomainType that contains several name/value pairs along with a Domain column that identifies rows that belong together. I have two C# classes called PackageType and ComponentType that both house their data in this same table with their Domain values being "PackageType" and "ComponentType" respectively. I thought I could use the NHibernate discrimator concept in my hbm.xml files to define these but every time I query for PackageTypes in my app I get back all rows from the DomainType table.

At this point I'm not sure if my mapping logic/syntax is bad or if I'm just misunderstanding the concept for discriminators. These are not subclasses after all so maybe this isn't the right strategy (?).

Here's the mapping file for my PackageType table:

 <class name="PackageType" table="DomainType" 
    discriminator-value="PackageType" dynamic-update="true">

    <id name="Id" column="Id" type="Int32" unsaved-value="0">
       <generator class="identity" />
    </id>

    <discriminator column="Domain" type="AnsiString" not-null="true" />

    <property name="Description" column="Description" 
     type="AnsiString" length="100" not-null="true" />
 </class>

Here's the C# code that returns all rows from the DomainType table (even ones where Domain="ComponentType"):

IEnumerable<PackageType> rslt = GetSession().Query<PackageType>().ToList();

Upvotes: 0

Views: 319

Answers (1)

MartinB
MartinB

Reputation: 21

You need to define an abstract class DomainType that both PackageType and ComponentType inherit from, then create a single mapping document DomainType.hbm.xml which contains the mapping for both of your subclasses. This is referred to Table-per-class-hierarchy in the NHibernate reference documentation.

<hibernate-mapping namespace=" ... " assembly=" ... ">
  <class name="DomainType" abstract="true" table="DomainType">
    <id name="Id" column="Id" type="Int32" unsaved-value="0">
       <generator class="identity" />
    </id>
    <discriminator column="Domain" type="AnsiString" not-null="true" />
    <subclass name="PackageType" discriminator-value="PACKAGE">
      <property .../>
    </subclass>
    <subclass name="ComponentType" discriminator-value="COMPONENT">
      <property .../>
    </subclass>
  </class>
</hibernate-mapping>

Then you can create a query for PackageType or ComponentType.

Upvotes: 1

Related Questions