如何使用 NHibernate 联合子类映射抽象属性?
Posted
技术标签:
【中文标题】如何使用 NHibernate 联合子类映射抽象属性?【英文标题】:How to map an abstract property with NHibernate union subclass? 【发布时间】:2012-10-06 18:41:25 【问题描述】:在这里参考 Ayende 的帖子: http://ayende.com/blog/3941/nhibernate-mapping-inheritance
我有类似的情况,可以通过稍微扩展上述帖子的联合子类映射,通过向 Party 添加一个抽象的 Name-property。模型如下:
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();
查询根本不匹配 Persons,而是使用来自公司 union-subclass 的映射。因此,当使用 Party 参数化时,查询似乎与使用 Company 参数化时基本相同(查询的 WHERE 子句是:WHERE this_.company_name = ((E'firstname lastname')::text))
关于我可能出错的地方以及如何实现我所追求的目标的任何指示?
【问题讨论】:
【参考方案1】:这可能是因为您使用了 NHibernate 无法确定的属性内部的逻辑。由于您已经为 Name 字段定义了公式,因此最好将它们保留为标准属性。因此,如果您按以下方式更正实体,它应该可以工作
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;
【讨论】:
我尝试了这种方法,但不幸的是行为保持不变。我尝试使用对被覆盖属性的属性访问以及带有支持字段的字段访问,在仅覆盖不带 setter 的 getter 时将 setter 添加到抽象名称(覆盖时需要)。【参考方案2】:显然这是 NHibernate 3.x 的一个已知问题: https://nhibernate.jira.com/browse/NH-2354?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
【讨论】:
以上是关于如何使用 NHibernate 联合子类映射抽象属性?的主要内容,如果未能解决你的问题,请参考以下文章
如何在nHibernate中映射一个继承抽象类并同时实现接口的类?