我有一个表T0,其中有一条外键FK和一条判别B,根据B去决定FK是到T1还是T2,这个逻辑是比较复杂的。我承认这是数据库设计的缺陷,但是由于数据库已经成型,所以不可能再改了,我想只能通过设计一个好的DataAccess层来解决这个问题。
我想的是这样的,这样郁闷的关联,简单地靠ORM估计是没法解决了,但是总的来说这个应用的实体类还不少,所以我不想放弃ORM的便利性。我想的是把所有数据访问都封装起来,完全不对业务逻辑层暴露任何细节,也就是说——有多少业务逻辑方法,就对应多少数据访问方法给它一对一的调用。而访问关联的时候就在数据层提供形如IList<TypeA> GetTypaA(TypeB obj)这样的一个方法,来访问obj的Many端,具体细节还是全不暴露给数据访问层。
这样的话的确再复杂的关联都可以解决,反正数据层的功力是无限的,判断多少都行。但是就存在一个问题,数据访问的方法和业务逻辑的方法完全是一一对应了,全然没有可复用性了,就算像单例的CRUD是可以稍稍复用的,但是总体来说这两层直接的代码还是感觉有太大的重叠。
希望大家给我出个好点的点子,谢谢。
可能是理解力不够,几遍下来还是没能完全明白你说的问题重点。对于获取关联的方法
IList GetTypeA(TypeB obj)
似乎不能配合你的表 T0, T1, T2 进行表达。针对表的各自实体类 T0, T1, T2 你是否可尝试用这样的方法访问关系数据:
IList GetDatas<T>(T0 t)
当 t 的 B 条件指向 T1 时,就调用
IList<T1> myFkDatas = GetDatas<T1>(T0 t);
当 t 的 B 条件指向 T2 时,就调用
IList<T2> myFkDatas = GetDatas<T2>(T0 t);
相当于定义一个泛型方法。
为了便于查找相关主键表数据,建议对两张(或多张)主键表的实体类创建同一个接口,比如 T1, T2 都是实现接口 IT0Fk, 该接口定义如下
interface IT0FK{
T0FKColumn{get;}
}
假设 T0 的字段 fkTId 指向 T1 的字段 TId 和 T2 的字段 TId, 那么
class T1: IT0FK{
...
T0FKColumn{get{return this.TId};}
}
class T2: IT0FK{
...
T0FKColumn{get{return this.TId};}
}
则泛型方法实现为
IList<T> GetDatas<T> where T: IT0FK (T0 t){
//查找所有 T.T0FKColumn = t.fkTId 的 T,并返回 IList
...
}
如此获取多种类的主键表数据就可以统一为一个泛型方法,而避免重复编码了。