Question

Referring to Ayende's post here: http://ayende.com/blog/3941/nhibernate-mapping-inheritance

I have a similar situation that can be reached by extending the union-subclass mapping of the above post a bit, by adding an abstract Name-property to the Party. The model would be as follows:

public abstract class Party
{
    public abstract string Name { get; }
}

public class Person : Party
{
    public override string Name { get { return this.FirstName + " " + this.LastName; } }

    public virtual string FirstName { get; set; }
    public virtual string LastName { get; set; }
}

public class Company : Party
{
    public override string Name { get { return this.CompanyName; } }
    public virtual string CompanyName { get; set; }
}

I'm looking for a mapping that would allow me to query over the parties in the following manner:

session.QueryOver<Party>().Where(p => p.Name.IsLike("firstname lastname")).List();

The mapping I'm using:

<class name="Party" table="`party`" abstract="true">
<id access="backfield" name="Id">
  <column name="Id" />
  <generator class="sequence">
    <param name="sequence">party_id_seq</param>
  </generator>
</id>
<union-subclass name="Person" table="`person`">
  <property name="Name" formula="first_name || ' ' || last_name" update="false" insert="false" access="readonly">
  </property>
  <property name="FirstName">
    <column name="first_name" />
  </property>
  <property name="LastName">
    <column name="last_name" />
  </property>
</union-subclass>
<union-subclass name="Company" table="`company`">
  <property name="Name" access="readonly" update="false" insert="false">
    <column name="company_name" />
  </property> 
  <property name="CompanyName">
    <column name="company_name" />
  </property>
</union-subclass>

For both

session.QueryOver<Person>().Where(p => p.Name.IsLike("firstname lastname")).List();

and

session.QueryOver<Company>().Where(p => p.Name.IsLike("companyName")).List();

this behaves as I'd expect, and I can query over the name and get the matching results. However, when I do

session.QueryOver<Party>().Where(p => p.Name.IsLike("firstname lastname")).List();

The query doesn't match the Persons at all, but uses the mapping from the union-subclass of the company. So when parametrized with Party, the query seems to be essentially the same as when parametrized with Company (the WHERE-clause of the query is: WHERE this_.company_name = ((E'firstname lastname')::text))

Any pointers about where I might be going wrong and how to achieve what I'm after?

Was it helpful?

OTHER TIPS

It would be because you were using the logic inside the properties, which NHibernate would be unable to determine. Since you have already defined the formulas for the Name field it's best to keep them as standard properties. So if you correct the entities as follows, it should work

public abstract class Party
{
    public abstract string Name { get; }
}

public class Person : Party
{
    public virtual string Name { get; set; }
    public virtual string FirstName { get; set; }
    public virtual string LastName { get; set; }
}

public class Company : Party
{
    public virtual string Name { get; set; }
    public virtual string CompanyName { get; set; }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top