2012-11-21 79 views
0

采取以下类别:继承和延迟加载NHibernate的

public class Employee 
{ 
    public Employee Manager { get; set; } 
} 

public class ShopFloorEmployee : Employee { ... } 

public class OfficeEmployee : Employee { ... } 

public class Department 
{ 
    public Employee Manager { get; set; } 
} 

,这里是NHibernate的映射文件:

<?xml version="1.0" encoding="utf-8" ?> 
    <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" 
        namespace="Domain.Entities" 
        assembly="Domain"> 
    <class name="Employee"> 
     <id name="Id" column="Id" type="long"> 
     <generator class="identity"/> 
     </id> 
     <discriminator column="Type" type="string"/> 
     <many-to-one name="Manager" class="Employee" column="ManagerId" lazy="proxy" /> 

     <subclass name="ShopFloorEmployee" discriminator-value="ShopFloorEmployee" extends="Employee"/> 
     </subclass> 

     <subclass name="OfficeEmployee" discriminator-value="OfficeEmployee" extends="Employee"/> 
     </subclass> 

    </class> 
    </hibernate-mapping> 

    <?xml version="1.0" encoding="utf-8" ?> 
    <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" 
        namespace="Domain.Entities" 
        assembly="Domain"> 
    <class name="Department"> 
     <id name="Id" column="Id" type="long"> 
     <generator class="identity"/> 
     </id> 
     <discriminator column="Type" type="string"/> 
     <many-to-one name="Manager" class="Employee" column="ManagerId" lazy="proxy" /> 
    </class> 
    </hibernate-mapping> 

这些代理似乎是造成我的问题。例如,如果我加载一个部门,那个部门的经理(我们称他为Bob,他是一个ShopFloorEmployee)将是EmployeeProxy类型。然后,在同一个会话中,如果我专门加载所有ShopFloorEmployees的列表,它们将全部属于ShopFloorEmployee类型,除了Bob,其将是EmployeeProxy类型。然后,我根本无法将Bob作为ShopFloorEmployee,因为它遵循不同的继承路径。

为了避免每次加载部门或员工时递归地加载负载的员工通过他们的经理代理是必要的。

我在这里做了一些根本性的错误,或者这是NHibernate的怪癖吗?如果这是一个怪癖,那么是否有解决方法?我已经考虑在加载部门之后明确地关闭会话,但这看起来太过分了。

+0

如果人们需要它,当我得到片刻时,我将添加查询代码。 –

回答

3

此问题的常见解决方法是增加一个Self属性来访问非代理型:

public virtual Employee Self 
{ 
    get { return this; } 
} 

然后你可以检查Bob.Self is ShopFloorEmployee

就我个人而言,我非常谨慎地使用继承,我会在这里使用“角色”属性而不是子类。

+0

这是一个很好的解决方案,可以解决现有域中的问题。如果我从一开始就设计它,我会使用khelland的答案,但这在这种情况下最有帮助。 –

2

这是一个普通的NHibernate pitfall。尝试将Manager引用更改为No proxy association

+0

我不知道为什么这个不适合我,很可能我做错了什么。我正在尝试修复复杂域中的问题。如果我从一开始就知道这一点,我可以设计它,并且这将是正确的路。 –