2012-11-21 116 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

我不知道爲什麼這個不適合我,很可能我做錯了什麼。我正在嘗試修復複雜域中的問題。如果我從一開始就知道這一點,我可以設計它,並且這將是正確的路。 –