2010-03-16 45 views
1

我有一类结构像下面NHibernate的代理创建

class Container 
{ 
    public virtual int Id { get; set; } 
    public IList<Base> Bases { get; set; } 
} 

class Base 
{ 
    public virtual int Id { get; set; } 
    public virtual string Name { get; set; } 
} 

class EnemyBase : Base 
{ 
    public virtual int EstimatedSize { get; set; } 
} 

class FriendlyBase : Base 
{ 
    public virtual int ActualSize { get; set; } 
} 

现在,当我在会话中寻找一个特定的容器通常它给我的具体EnemyBase,并在基地集合FriendlyBase对象。那么我可以(如果我愿意的话)将它们转换成具体的类型,并对它们做一些特定的事情。

但是,有时候我得到了一个不能转换为具体类型的“Base”类的代理。同样的方法同时使用,唯一的例外是在我得到代理的情况下,我已经将一些相关实体添加到会话中(认为友好的基础具有人员集合或类似的东西)。

有什么办法可以阻止它做代理创建,为什么它会选择在某些情况下做到这一点?

UPDATE

的映射与fluentnhibernate的自动映射功能生成,但出口

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" default-access="property" auto-import="true" default-cascade="none" default-lazy="true"> 
    <class xmlns="urn:nhibernate-mapping-2.2" mutable="true" name="Base" table="`Base`"> 
    <id name="Id" type="System.Int32, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> 
     <column name="Id" /> 
     <generator class="MyIdGenerator" /> 
    </id> 
    <property name="Name" type="String"> 
     <column name="Name" /> 
    </property> 

    <joined-subclass name="EnemyBase"> 
     <key> 
     <column name="Id" /> 
     </key> 
     <property name="EstimatedSize" type="Int"> 
     <column name="EstimatedSize" /> 
     </property> 

    </joined-subclass> 
    <joined-subclass name="FriendlyBase"> 
     <key> 
     <column name="Id" /> 
     </key> 
     <property name="ActualSize" type="Int"> 
     <column name="ActualSize" /> 
     </property> 

    </joined-subclass> 
    </class> 
</hibernate-mapping> 

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" default-access="property" auto-import="true" default-cascade="none" default-lazy="true"> 
    <class xmlns="urn:nhibernate-mapping-2.2" mutable="true" name="Container" table="`Container`"> 
    <id name="Id" type="System.Int32, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> 
     <column name="Id" /> 
     <generator class="MyIdGenerator" /> 
    </id> 
    <bag cascade="all-delete-orphan" inverse="true" lazy="false" name="Bases" mutable="true"> 
     <key> 
     <column name="ContainerId" /> 
     </key> 
     <one-to-many class="Base" /> 
    </bag> 
    </class> 
</hibernate-mapping> 

UPDATE

当是这个样子,现在我已经告诉NH从不延迟加载任何它automaps,不是理想的,如果我在未来需要的功能,但它似乎现在工作。

+0

你的映射是什么样的? – snicker 2010-03-16 16:22:08

回答

0

您可以将类型定义为抽象类型吗?这可能会给你一个错误,因为nHibernate正在尝试,但它可能会指向你“为什么”。

+0

我将它标记为抽象,结果完全相同。 – 2010-03-16 16:13:38

1

据我所知,如果您使用myProxiedBase = Session.Load<Base>(myBase.Id)您将永远得到一个基本对象的代理。如果你想要一个EnemyBase对象,你必须拨打Session.Load<EnemyBase<(myProxiedBase.Id)

检查第17章中的文档本节:

它说明了一点,比我能和可能的解决方法更好。

+0

在这种情况下,我得到了Container对象,而不是直接获取“Base”类之一。通常情况下,收集填充具体的课程,除非我先在会话中做了其他事情。我只是不确定是什么触发它 – 2010-03-16 16:18:31

+0

如果您有其他对象引用了基础对象并加载它们,它可能会将代理创建为基础对象并将它们缓存在会话中。我假设你懒惰加载你的实体? – snicker 2010-03-16 16:20:13

+0

在这种情况下,我已经告诉它不要因为容器总是需要它的孩子(我现在只在一个页面上使用它) – 2010-03-16 16:39:16