2012-10-06 73 views
3

参考Ayende的帖子在这里: http://ayende.com/blog/3941/nhibernate-mapping-inheritance如何使用NHibernate联合子类映射抽象属性?

我有一个可以通过扩展上述职位的工会子类映射位,通过增加一个抽象的名称属性党达成了类似的情况。该模型将如下:

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; } 
} 

我正在寻找一个映射,让我查询了各方以下列方式:

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

我使用的映射:

<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> 

对于这两种

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

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

这样做的行为与我的预期,我可以查询名称并获得匹配的结果。然而,当我做

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

查询不匹配,在所有的人,但是从公司的工会子类使用的映射。因此,当使用Party进行参数化时,查询似乎基本上与使用Company进行参数化时相同(查询的WHERE子句是:WHERE this_.company_name =((E'firstname lastname'):: text))

任何关于我可能会出错的指针以及如何实现我所追求的内容?

回答

0

这将是因为你使用了NHibernate无法确定的属性内部的逻辑。由于您已经为名称字段定义了公式,因此最好将它们保留为标准属性。所以,如果你纠正实体如下,它应该工作

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; } 
} 
+0

我尝试了这种方法,但不幸的是行为保持不变。当尝试在覆盖属性上使用属性访问时,向抽象名称(在覆盖时需要)添加setter,以及在不使用setter时仅覆盖getter时使用后台字段访问字段。 – proge