2009-08-28 60 views
2

考虑将这两个类映射到同一个表。一个是通过mutable =“false”只读的。映射到同一个表(一次只读)的两个类必须按正确的顺序?

<class name="Funder" table="funder"> 
    <id name="id"> 
     <generator class="identity" /> 
    </id> 
    <property name="funder_name" /> 
    <property name="contact_name" /> 
    <property name="addr_line_1" /> 
    <property name="addr_line_2" /> 
    <property name="addr_line_3" /> 
    <property name="city" /> 
    <many-to-one name="state" column="state_id" foreign-key="FK_funder_state_id" fetch="join" /> 
    <property name="zip_code" length="10" /> 
    <property name="phone_number" length="30" /> 

    <property name="create_dt" update="false" not-null="true" /> 
    <many-to-one name="create_by" column="create_by" not-null="true" update="false" foreign-key="FK_funder_create_by" fetch="join" /> 
    <property name="last_update_dt" insert="false" /> 
    <many-to-one name="last_update_by" insert="false" foreign-key="FK_funder_last_update_by" fetch="join" /> 

    </class> 

    <class name="FunderSimple" table="funder" schema-action="none" mutable="false"> 
    <id name="id"> 
     <generator class="identity" /> 
    </id> 
    <property name="funder_name" /> 
    <property name="contact_name" /> 
    <property name="phone_number" /> 
    </class> 

如果我出资人之前移动FunderSimple映射映射我的架构并没有正确产生。如果我像上面那样离开它,它就会起作用。

设计这是什么?看起来好像schema-action =“none”粘在table_name上,后来到同一个表的映射不会生成模式。

我这样做是因为我有另一个名为Contract的类,它有一个外键给出资者表。但是,从合同对象引用时,我不需要所有的资助者列。

<many-to-one name="funder_simple" column="funder_id" foreign-key="FK_contract_funder_id" fetch="join" /> 

出资者不从FunderSimple继承。

我是否应该使用不同的技术从外键表中只提取列的子集?多对一是设置外键的唯一方法吗?

使用版本2.1.0.4000

回答

2

对于这种情况,我使用投影来代替。 我从来没有将两种类型映射到同一个表(除非出于继承的原因)。

所以,我在这种情况下做的是:

创建FunderSimple类,并导入它,以便它是由NHibernate的知道:

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"> 
    <import class="MyNamespace.FunderSimple" /> 
</hibernate-mapping> 

一旦你做到了这一点,你可以使用ICriteria API在您的'Funder'类型上创建查询,但是,您可以指定您希望NHibernate返回FunderSimple的实例。 通过这样做,NHibernate足够智能地生成简化的SQL查询,该查询仅检索填充FunderSimple类实例所需的列。

这是这样完成的:

ICriteria crit = session.CreateCriteria (typeof(Funder)); 
// add some expressions ... 
crit.Add (...); 

// Now, set the projection, and specify that FunderSimple should be returned 
crit.SetProjection (Projections.ProjectionList() 
         .Add (Projections.Property ("Id"), "Id") 
         .Add (Projections.Property ("funder_name"), "funder_name") 
         .Add (Projections.Property ("phone_number"), "phone_number")); 

crit.SetResultTransformer (Transformers.AliasToBean (typeof(FunderSimple))); 

crit.List <FunderSimple>(); 
+0

有趣......但是,请问从合同角度映射这项工作。我是否会将多对一改回到繁重的Funder对象,并以某种方式将其映射到仅加载FunderSimple? – dotjoe 2009-09-02 16:06:13

+1

合同应与“资助者”有关系,因为“资助者”是您的实体。 我只看到FunderSimple只是作为某种助手/容器来显示“资助者”列表,而您并不需要拥有完整的资助者实体。 为什么要在检索合同实例时检索'FunderSimple'实例? – 2009-09-02 19:59:26

+0

非常多,所以我不必将Funder的所有不需要的外键(例如create_by和last_update_by键)都加入Staff表中......这反过来又会导致Staff表中多个键的更多连接。就合同而言,FunderSimple字段是我唯一需要的字段。我怀疑每次拿到合同都会加入所有这些不需要的表格,这会影响业绩。但是,我只是希望有一种方法来解决这个问题,只查询我需要的东西。 – dotjoe 2009-09-02 20:15:29

相关问题