天天看點

使用Castle.ActiveRecord的注意事項之三:繼承

 學習繼承,純屬意外,資料庫的設計者硬要把A,B,C三個完全不同的對象存在同一張表中,并振振有詞說A,B,C三個對象的内容比較類似,都有Name,Address等屬性,加一個Type辨別就可以了。事後證明這個是資料庫的一大敗筆,因為這麼項目中有D對象,D對象與A對象是一對一關系,與B對象是一對多關系,與C對象是多對多關系......

     這可苦了我了,按照一個表一個對象的思路,原來A,B,C作為一個對象 O,裡面有個Type屬性,當Type為1的時候為A,為2的時候為B,為3的時候為C。D對象中,幾個屬性:O(表示A),OList(表示B),OList2(表示C)。開發的過程中,開發人員都問我,D裡面的那些O到底表示什麼? 當要搜尋出所有的A對象,結果ActiveBase類帶的find方法會搜尋出所有的O對象。 而且由于前期存儲資料的馬虎,很多人在存的時候沒有注明Type,導緻資料庫裡面的資料一片混亂.......

        幸好後來看到了關于Hibernate繼承的文章,一看Castle裡面ActiveRecord果然也有。

     一、單表關聯繼承、用于多個對象使用同一表的情況。

   對于上面的情況,設計了

使用Castle.ActiveRecord的注意事項之三:繼承
使用Castle.ActiveRecord的注意事項之三:繼承

Code

 [ActiveRecord(DiscriminatorColumn = "Type", DiscriminatorType = "int", DiscriminatorValue = "0", Table = "T_PRI_DEPARTMENT")]

    public class BaseO: ActiveRecordBase<BaseO>

    {

        .

    }

其中,DiscriminatorColumn是辨別的字段名字,DiscriminatorType是字段資料類型,該BaseO對象一般用不到。可以加一個sealed讓其不可被執行個體化。另外寫了

使用Castle.ActiveRecord的注意事項之三:繼承
使用Castle.ActiveRecord的注意事項之三:繼承

 [ActiveRecord(DiscriminatorValue = "1")]

    public class AVO : BaseO

以及B,C的對象,不同的隻是類屬性标簽裡面,DiscriminatorValue不一樣。

        至此,A,B,C三個對象的相關存儲(Save),查詢(Find)方法并行不悖。其他地方調用再用不用為名字困惑,為忘記辨別(Type)而煩惱了。

        以上是ActiveRecord裡面的單表關聯繼承。

二、多表關聯繼承

         對于一個表一個對象的情況比較常見,但是也經常遇到兩個表一個對象的情況。比如我的上司就喜歡把使用者的表設計成兩張表,一個表User_Account,存有關系統的LoginName,PASSWORD等資訊,一個User_Information存該使用者的NameCn,Address等資訊。理由是,有可能存某些資訊到User_information裡面,但是該使用者沒有登入資訊。對于該設計我持保留意見。

        但代碼還是得寫,之前設計了AccountVO,InformationVO,二者一對一關系。每次增删查都要分兩次操作,相當痛苦。

        其實這裡可以用多表關聯繼承。

       設計兩個對象,一個作為基類

使用Castle.ActiveRecord的注意事項之三:繼承
使用Castle.ActiveRecord的注意事項之三:繼承

    /// <summary>

    /// Base對象

    /// </summary>

    [ActiveRecord("T_PRI_INFORMATION"),JoinedBase]

    public class BaseInformation: ActiveRecordBase<BaseInformation>

    {  

再設計一個AccountVO,繼承BaseInformation,對應另外一張Account表

使用Castle.ActiveRecord的注意事項之三:繼承
使用Castle.ActiveRecord的注意事項之三:繼承

/// <summary>    

/// 單表繼承測試類 

/// </summary>

[ActiveRecord("T_PRI_ACCOUNT")]

public class AccountVO : BaseInformation

{

}

這樣,AccountVO對象就映射了兩張表,不用再每次為增加修改一個使用者而修改兩個對象了。

使用Castle.ActiveRecord的注意事項之三:繼承
使用Castle.ActiveRecord的注意事項之三:繼承

new public static AVO[] FindAll()

        {

            return ((AVO[])(ActiveRecordBase.FindAll(typeof(AVO))));

        }

        new public static AVO Find(int aId)

           return ((AVO)(ActiveRecordBase.FindByPrimaryKey(typeof(AVO), aId)));

        new public static AVO[] FindAllByProperty(string prop,Object o)

            return ((AVO[])(ActiveRecordBase.FindAllByProperty(typeof(AVO),prop,o)));