DBO -- 实体设计 -- 对象关联还是ID关联

在构建一个三层架构的系统的时候,实体的设计,是完全的面向对象,还是采用ID关联的平板对象,这是一个问题。写一点个人的观点。

假设在一个用户管理系统中,存在单位和用户两个实体,

表结构如下:

datamodel.GIF


我们先看对象关联情况下实体的设计:


///   <summary>
    
///  单位实体
    
///   </summary>
     public   class  Org
    {
        
private   int  _OrgId;
        
///   <summary>
        
///  单位id
        
///   </summary>
         public   int  OrgId
        {
            
get  {  return  _OrgId; }
            
set  { _OrgId  =  value; }
        }

        
private   string  _OrgName;
        
///   <summary>
        
///  单位名
        
///   </summary>
         public   string  OrgName
        {
            
get  {  return  _OrgName; }
            
set  { _OrgName  =  value; }
        }

        
private  Org _ParentOrg;
        
///   <summary>
        
///  父单位
        
///   </summary>
         public  Org ParentOrg
        {
            
get  {  return  _ParentOrg; }
            
set  { _ParentOrg  =  value; }
        }

        
private  IList < Org >  _ChildrenOrg;
        
///   <summary>
        
///  子单位列表
        
///   </summary>
         public  IList < Org >  ChildrenOrg
        {
            
get  {  return  _ChildrenOrg; }
            
set  { _ChildrenOrg  =  value; }
        }

        
private  IList < User >  _Users;
        
///   <summary>
        
///  单位的用户
        
///   </summary>
         public  IList < User >  Users
        {
            
get  {  return  _Users; }
            
set  { _Users  =  value; }
        }
    }

  ///   <summary>
    
///  用户实体
    
///   </summary>
     public   class  User
    {
        
private   int  _UserId;
        
///   <summary>
        
///  用户id
        
///   </summary>
         public   int  UserId
        {
            
get  {  return  _UserId; }
            
set  { _UserId  =  value; }
        }
        
        
private   string  _UserName;
        
///   <summary>
        
///  用户名
        
///   </summary>
         public   string  UserName
        {
            
get  {  return  _UserName; }
            
set  { _UserName  =  value; }
        }

        
private  Org _OwnerOrg;
        
///   <summary>
        
///  用户所属的单位
        
///   </summary>
         public  Org OwnerOrg
        {
            
get  {  return  _OwnerOrg; }
            
set  { _OwnerOrg  =  value; }
        }


这是两个非常面向对象的实体--数据实体,那么我们在使用的时候会遇到什么问题呢?

对象关联在一起,不可避免的遇到关联加载的问题--当我获取一个用户实体的时候,为满足完整性,我也必须从数据库中取出一个单位实体。

为了解决这么问题,大多数流行的ORM框架提供了lazy-load特性--延迟加载,只有当真正访问到管理对象的时候才把对象从数据库中取出来。

看似问题解决了,仔细分析一下,那些延迟加载实现的怎么样???

实现lazy-load的大多数方法都要求侵入实体代码,如NHibanate,它的实体类属性要求必须是虚属性(最新版的NH),为什么?应为它要延迟加载,就必须拦截属性的调用(好像它是利用castle的动态代理实现的)。

可能你会说,实体类属性都写成虚的(virtual)还是可以接受的,那么,我们看另外的问题:

问题1:要延迟加载,取出一个实体后,数据库连接一定不能立即关闭, 数据库连接关闭了,代码还怎么延迟访问数据库取数据?于是,数据库连接关闭的代码必须写到UI层。

问题1:现在流行的一下AOP,IOC框架很多都支持分布式部署,在分布式部署的情况下,我们考虑关联实体会怎么样?远程的一个客户端取到实体,每次访问其他关系实体属性时都会在一次请求服务器端!
你可能会说,在分布式部署的情况下我不采用延迟加载不就可以了。请注意一点:
这里所说的在AOP框架支持下的分布式部署,是“透明”的分布式部署,即UI层开发的时候不需要要考虑分布式的问题(那么,你是不是要延迟加载了),系统开发好了,如果需要,可以通过配置AOP框架实现分布式,这时,原有的采用延迟加载的页面就会碰到问题。


我们再看ID关联情况下实体的设计:

///   <summary>
    
///  单位实体
    
///   </summary>
     public   class  Org
    {
        
private   int  _OrgId;
        
///   <summary>
        
///  单位id
        
///   </summary>
         public   int  OrgId
        {
            
get  {  return  _OrgId; }
            
set  { _OrgId  =  value; }
        }

        
private   string  _OrgName;
        
///   <summary>
        
///  单位名
        
///   </summary>
         public   string  OrgName
        {
            
get  {  return  _OrgName; }
            
set  { _OrgName  =  value; }
        }

        
private   int  _ParentId;
        
///   <summary>
        
///  父单位id
        
///   </summary>
         public   int  ParentId
        {
            
get  {  return  _ParentId; }
            
set  { _ParentId  =  value; }
        }     

    }

  ///   <summary>
    
///  用户实体
    
///   </summary>
     public   class  User
    {
        
private   int  _UserId;
        
///   <summary>
        
///  用户id
        
///   </summary>
         public   int  UserId
        {
            
get  {  return  _UserId; }
            
set  { _UserId  =  value; }
        }

        
private   int  _orgId;
        
///   <summary>
        
///  所属单位id
        
///   </summary>
         public   int  OrgId
        {
            
get  {  return  _orgId; }
            
set  { _orgId  =  value; }
        }

        
private   string  _UserName;
        
///   <summary>
        
///  用户名
        
///   </summary>
         public   string  UserName
        {
            
get  {  return  _UserName; }
            
set  { _UserName  =  value; }
        }
        
    }

首先从代码上,比上面的简单些吧。

这样的实体,虽然有那么一点不“面向对象”,但绝对避免了“面向对象”时遇到的问题。

我们这群人的工作,总是在 发现问题-〉解决问题-〉引起新的问题 -〉解决问题 中度过的。

OK,ID关联的实体设计方法同样遇到了新问题:我要处理多表的数据怎么办?我要跨表查询怎么办?

解决方案就是:采用关联实体,或者称为视图实体.

举个例子: UI层要显示一个用户列表, 同时显示出每个用户所属的组织机构名 , 怎么办?
Easy! 只要设计一个关联实体:

   ///   <summary>
    
///  具有单位名称的用户关联实体
    
///   </summary>
     public   class  UserWithOrgInfo : User
    {
        
private   string  _OrgName;
        
///   <summary>
        
///  单位名
        
///   </summary>
         public   string  OrgName
        {
            
get  {  return  _OrgName; }
            
set  { _OrgName  =  value; }
        }
    }

或许,你要说,我不需要这么多属性,用户的属性加上单位的属性太多了,UI层显示的时候根本不需要!
OK,我们可以建立一个视图实体:

  ///   <summary>
    
///  用户视图实体
    
///   </summary>
     public   class  UserView
    {
        
private   string  _UserName;
        
///   <summary>
        
///  用户名
        
///   </summary>
         public   string  UserName
        {
            
get  {  return  _UserName; }
            
set  { _UserName  =  value; }
        }

        
private   string  _OrgName;
        
///   <summary>
        
///  单位名
        
///   </summary>
         public   string  OrgName
        {
            
get  {  return  _OrgName; }
            
set  { _OrgName  =  value; }
        }

    }

这下满足了吧! 需要几个属性,就返回几个属性.

问题解决了!!!!!!!!!

但是新的问题又来了:

采用ID关联设计实体,仍然要写大量的数据库操作代码,如果采用一些ORM框架,他们对ID关联的实体设计又没有考虑到进行支持,因为现有的ORM框架大多都是为了应对“面向对象”的实体设计而开发的. NHibenate,IBatics.net,NBear,DLinq皆如此。


这就是DBO的由来,没有人会做无用功,也不会有人喜欢发明一个一样的轮子,每个轮子都应该有它适合走的道路。

DBO,为ID关联实体设计提供数据操作支持的ORM工具。

DBO从2007-5-20开始开发,基本功能完成,不足之处总归是有的,任者见任,智者见智,欢迎有兴趣的朋友提出意见。

DBO 介绍,见:

http://www.cnblogs.com/jianyi0115/archive/2007/06/04/771325.html
 










  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值