0

参加以下课程:

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 的列表,那么除了 Bob 之外,它们都是 ShopFloorEmployee 类型,他的类型是 EmployeeProxy。然后我根本无法将 Bob 转换为 ShopFloorEmployee,因为它遵循了不同的继承路径。

每次我加载部门或员工时,代理都需要避免通过他们的经理递归加载员工负载。

我在这里做一些根本错误的事情,还是这是 NHibernate 的一个怪癖?如果这是一个怪癖,那么是否有解决方法?我曾考虑在加载部门后明确关闭会话,但这似乎太老套了。

4

3 回答 3

3

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

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

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

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

于 2012-11-21T15:45:23.327 回答
2

这是一个常见的NHibernate 陷阱。尝试更改对No proxy associationManager的引用。

于 2012-11-21T11:36:47.657 回答
1

我有一个类似的问题,请参见此处: 流利的休眠多态性。如何检查类的类型

我选择使用基于访客模式的解决方案

你不需要关闭延迟加载,也不需要使用有趣的属性来返回 self 对象

于 2012-11-24T17:13:00.107 回答