2011-07-24 87 views
1

比方说,我有以下几点:映射集/休眠

public interface IPet 
{ 
    long? Id { get; set; } 
    string Name { get; set; } 
} 

public class Cat : IPet 
{ 
    public virtual long? Id { get; set; } 
    public virtual string Name { get; set; } 
} 

public class Dog : IPet 
{ 
    public virtual long? Id { get; set; } 
    public virtual string Name { get; set; } 
} 

而下面的映射:

<class name="Cat" table="`Cat`" > 
    <id name="Id" type="long"> 
    <generator class="identity"/> 
    </id> 
    <property name="Name"/> 
</class> 

<class name="Dog" table="`Dog`" > 
    <id name="Id" type="long"> 
    <generator class="identity"/> 
    </id> 
    <property name="Name"/> 
</class> 

现在,当我执行以下操作:

IList<IPet> pets = session.CreateCriteria<IPet>().List<IPet>(); 

由于隐含的多态性,一个很好的功能,它返回所有的猫和狗。现在考虑这个:

public class PetShop 
{ 
    public long? Id { get; set; } 
    public List<IPet> Pets { get; set; } 
} 

<class name="PetShop" table="`PetShop`" > 
    <id name="Id" type="long"> 
    <generator class="identity"/> 
    </id> 
    <property name="Name"/> 
    <bag name="Pets" cascade="all"> 
    <key column="PetShopId"/> 
    <one-to-many class="IPet"/> 
    </bag> 
</class> 

我希望这将意味着宠物的收集将使用隐式多态来填充集合,而是我得到的错误协会引用未映射类:IntefaceCollectionExample.Domain.Entities.IPet“ 。我可以为IPet女巫创建一个映射表并仅包含Id,但这种感觉很不直观。我可以使用union-subclass,但是会失去使用generator class =“identity”的选项。我可以使用多对多,但我觉得在这种情况下这将会相当笨拙。

有什么我失踪了吗?有没有办法为IPet的接口创建映射,但不需要表,然后指定Cat和Dog实现这个。或者有没有比我上面列出的方法更好的方法来达到这个目标?

回答

1

隐多态性是not supportedone-to-many场景

您可以使用一个明确的继承策略(即从接口开始,必须映射整个层次结构),或者为集合和映射创建一个表格many-to-any

+0

当你说整个heirachy必须被映射时,你是否主张像我提到的那样有一个IPet表?看来,我想做的事情是无法完成的。这是一个耻辱 - 这将是一个不错的功能。 –

+0

@PaulTDavies:通过使用[Table per Concrete Class](http://www.nhforge.org/doc/nh/en/index.html#inheritance-tableperconcrete)策略,您可以避免为接口提供表格。但它不一定更好。 –