使用Castle.ActiveRecord的注意事项三:继承
 [ActiveRecord(DiscriminatorValue = "2")]
    [ActiveRecord(DiscriminatorValue = "2")] public class BVO : BaseO
    public class BVO : BaseO {
    { }
    }学习继承,纯属意外,数据库的设计者硬要把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果然也有。
一、单表关联继承
对于上面的情况,设计了
 [ActiveRecord(DiscriminatorColumn = "Type", DiscriminatorType = "int", DiscriminatorValue = "0", Table = "T_PRI_DEPARTMENT")]
        [ActiveRecord(DiscriminatorColumn = "Type", DiscriminatorType = "int", DiscriminatorValue = "0", Table = "T_PRI_DEPARTMENT")] public class BaseO: ActiveRecordBase<BaseO>
    public class BaseO: ActiveRecordBase<BaseO> {
    { .
        . .
        . .
        . }
    }其中,DiscriminatorColumn是标识的字段名字,DiscriminatorType是字段数据类型,该BaseO对象一般用不到。可以加一个sealed让其不可被实例化。另外写了
 [ActiveRecord(DiscriminatorValue = "1")]
      [ActiveRecord(DiscriminatorValue = "1")] public class AVO : BaseO
    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,二者一对一关系。每次增删查都要分两次操作,相当痛苦。
其实这里可以用多表关联继承。
设计两个对象,一个作为基类
 /// <summary>
     /// <summary> /// Base对象
    /// Base对象 /// </summary>
    /// </summary> [ActiveRecord("T_PRI_INFORMATION"),JoinedBase]
    [ActiveRecord("T_PRI_INFORMATION"),JoinedBase] public class BaseInformation: ActiveRecordBase<BaseInformation>
    public class BaseInformation: ActiveRecordBase<BaseInformation> {
    {   }
    }再设计一个AccountVO,继承BaseInformation,对应另外一张Account表
 /// <summary>
     /// <summary>     /// 集团客户信息表对象。单表继承测试
    /// 集团客户信息表对象。单表继承测试   /// </summary>
    /// </summary> [ActiveRecord("T_PRI_ACCOUNT")]
    [ActiveRecord("T_PRI_ACCOUNT")] public class AccountVO : BaseInformation
    public class AccountVO : BaseInformation {
    { }
    }
这样,AccountVO对象就映射了两张表,不用再每次为增加修改一个用户而修改两个对象了。
以上就是Castle.ActiveRecord里面的继承。源于Hibernate,所以Hibernate的相关里面里面都有。相关设置可以自己BAIDU一下。(自从有了ActiveRecord,好久没有写hibernate的hbm.xml映射文件了)
值得一提的是,使用了继承以后,如果使用的时候是直接继承ActiveRecordBase<T>以获得Find,FindByProperty等方法的,需要重写这些方法,不然会继承自基类的方法。如A.FindAll得到的是O对象,而出错。
 new public static AVO[] FindAll()
  new public static AVO[] FindAll() {
        { return ((AVO[])(ActiveRecordBase.FindAll(typeof(AVO))));
            return ((AVO[])(ActiveRecordBase.FindAll(typeof(AVO)))); }
        }
 new public static AVO Find(int aId)
        new public static AVO Find(int aId) {
        { 
             return ((AVO)(ActiveRecordBase.FindByPrimaryKey(typeof(AVO), aId)));
           return ((AVO)(ActiveRecordBase.FindByPrimaryKey(typeof(AVO), aId))); 
             }
        } 
        
 new public static AVO[] FindAllByProperty(string prop,Object o)
        new public static AVO[] FindAllByProperty(string prop,Object o) {
        {
 return ((AVO[])(ActiveRecordBase.FindAllByProperty(typeof(AVO),prop,o)));
            return ((AVO[])(ActiveRecordBase.FindAllByProperty(typeof(AVO),prop,o))); }
        }
 }
    } }
}
 
                    
                     
                    
                 
                    
                 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号