技术开发 频道

DBO实体设计的问题:选择对象关联还是ID关联

【IT168技术文档】
    在构建一个三层架构的系统的时候,实体的设计,是完全的面向对象,还是采用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 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框架实现分布式,这时,原有的采用延迟加载的页面就会碰到问题。
0
相关文章