DBO ( database object ) 使用手册

概述

代码霹雳啪啦写好了,要写文档了,感觉真的很难,无从下手。废话就不说了,进入正题。

DBO—database object operation toolkit . 说白了,又一个轮子—OR Mapping工具。  .net领域,这种轮子已经很多了:NHinerate,IBaitc.net,NBear等等。 轮子是圆的,但并不意味着十全十美。
 
之所以写DBO,源于几年来的设计习惯:我们利用面向对象的语言,嚷着要进行面向对象的设计,但企业程序设计中,三层的架构,真正按完全的面向对象设计来构建的有几个?

这是笔者习惯的设计方法:

三层结构:表现层,业务层,数据访问层,各层之间通过实体对象传递数据,实体对象跟数据库表结构基本一致,实体之间不会存在对象关联,而是通过ID关联(这应该不是一个面向对象的方法吧)。
 
功能强大的OR Mapping工具都支持关联表操作,关联表操作又会引起另外的问题:关联加载时的性能问题,于是,为解决这个问题,又提供了Lazy-load特性,这个特性实现的如何,暂不作评论。

数据库是平板数据的关联,我们的表现层页面,大多数情况下也是平板的(表格)。而对象,对象的关系却是一个树和网的关系。
 
笔者的设计观点:

三层架够的开发中,让面向对象见鬼去吧,我们还是采用平板数据。(当然不是贬低面向对象,DBO的的确确是用面向对象的思想开发出来的).

DBO核心功能

1.        利用特性(Attribute)配置实体映射信息。

2.       单表实体操作:实现对单个实体,单个表的增删改查。

3.       关联删除:可以一次将多级关联的实体删除。

4.      条件操作:按照强类型查询条件,进行单个实体,单个表的增删改查。查询条件支持任意拼凑。

5.         跨表查询支持:利用关联实体实现跨表查询,支持设置join方式。

6.        强类型查询语句:利用C#代码写sql.。(有点鸡肋,大家看看啦)。

记住一点:DBO中没有直接的对象关联,所有的对象关系通过特性指定。

没有了直接的对象关联,所有的实体类成了平板数据,避免了lazyload,和由lazy-load引起的其它问题。


DBO
的基本接口

基本会话接口

 /// <summary>
    
/// 基本实体操作
    
/// base operation to dbo
    
/// </summary>
    public interface IDboBaseSession 
    {
        
/// <summary>
        
/// 按照主键获取一个实体
        
/// get a entity from database by primary key
        
/// </summary>
        
/// <typeparam name="T"></typeparam>
        
/// <param name="keys"></param>
        
/// <returns></returns>
        T Get<T>(object keys) where T : classnew();

        
/// <summary>
        
/// 按照主键获取一个实体,支持多个主键
        
/// load a entity , suport many primary keys
        
/// </summary>
        
/// <typeparam name="T"></typeparam>
        
/// <param name="obj"></param>
        
/// <returns></returns>
        bool Load<T>(T obj) where T : classnew();

        
/// <summary>
        
/// 插入一个实体
        
/// insert a entity to database
        
/// </summary>
        
/// <typeparam name="T"></typeparam>
        
/// <param name="o"></param>
        
/// <returns></returns>
        int Insert<T>(T o) where T : classnew();

        
/// <summary>
        
/// 修改一个实体
        
/// update a entity to database
        
/// </summary>
        
/// <typeparam name="T"></typeparam>
        
/// <param name="o"></param>
        
/// <returns></returns>
        int Update<T>(T o) where T : classnew();

        
/// <summary>
        
/// 删除一个实体
        
/// delete a entity from database
        
/// </summary>
        
/// <typeparam name="T"></typeparam>
        
/// <param name="o"></param>
        
/// <returns></returns>
        int Delete<T>(T o) where T : classnew();

        
//int Delete<T>(T o, bool deleteRef) where T : class, new();

        
/// <summary>
        
/// 删除所有实体
        
/// delete all entity from the table
        
/// </summary>
        
/// <typeparam name="T"></typeparam>
        
/// <returns></returns>
        int DeleteAll<T>() where T : classnew();

        
//int Delete(Type t, object keyValue, bool delRef);

        
/// <summary>
        
/// 保存一个实体,插入或修改
        
/// insert or update a entity to the database
        
/// </summary>
        
/// <typeparam name="T"></typeparam>
        
/// <param name="o"></param>
        
/// <returns></returns>
        int Save<T>(T o) where T : classnew();

        
/// <summary>
        
/// 获取所有实体
        
/// load all entities from a table 
        
/// </summary>
        
/// <typeparam name="T"></typeparam>
        
/// <returns></returns>
        IList<T> LoadAll<T>() where T : classnew();
 
    }

条件会话接口 

/// <summary>
    
/// 条件操作
    
/// operation with query to dbo
    
/// </summary>
    public interface IDboConditionSession //: ICloseRequire 
    {
        
/// <summary>
        
/// 按照条件获取一个实体
        
/// get a entity with the conditon
        
/// </summary>
        
/// <typeparam name="T"></typeparam>
        
/// <param name="q"></param>
        
/// <returns></returns>
        T Get<T>(ConditionExpression q) where T : classnew();

        
/// <summary>
        
/// 按照条件修改实体
        
/// update a entity with the condition
        
/// </summary>
        
/// <typeparam name="T"></typeparam>
        
/// <param name="o"></param>
        
/// <param name="q"></param>
        
/// <returns></returns>
        int Update<T>(T o, ConditionExpression q) where T : classnew();

        
/// <summary>
        
/// 按照条件修改实体的某些字段
        
/// update a entity with the condition and only update the special fields
        
/// </summary>
        
/// <typeparam name="T"></typeparam>
        
/// <param name="o"></param>
        
/// <param name="q"></param>
        
/// <param name="fields"></param>
        
/// <returns></returns>
        int Update<T>(T o, ConditionExpression q, params IQueryField[] fields ) where T : classnew();

        
/// <summary>
        
/// 按照条件删除实体
        
/// delete entities with the contidition
        
/// </summary>
        
/// <typeparam name="T"></typeparam>
        
/// <param name="q"></param>
        
/// <returns></returns>
        int Delete<T>(ConditionExpression q) where T : classnew();

        
/// <summary>
        
/// 按照条件查询实体列表
        
/// query list of a entity with the condition
        
/// </summary>
        
/// <typeparam name="T"></typeparam>
        
/// <param name="q"></param>
        
/// <returns></returns>
        IList<T> Query<T>(ConditionExpression q) where T : classnew();

        
/// <summary>
        
/// 按照条件查询实体表格
        
/// query a table of a entity with the condition
        
/// </summary>
        
/// <typeparam name="T"></typeparam>
        
/// <param name="q"></param>
        
/// <returns></returns>
        DataTable QueryTable<T>(ConditionExpression q) where T : classnew();

        
/// <summary>
        
/// 按照条件查询关联实体列表
        
/// query a joined entity whth the condition
        
/// </summary>
        
/// <typeparam name="T"></typeparam>
        
/// <param name="q"></param>
        
/// <returns></returns>
        IList<T> JoinQuery<T>(ConditionExpression q) where T : classnew();

        
/// <summary>
        
/// 按照强类型sql语句查询实体列表
        
/// query list of a entity with a strong type sql 
        
/// </summary>
        
/// <typeparam name="T"></typeparam>
        
/// <param name="q"></param>
        
/// <returns></returns>
        IList<T> Query<T>(QueryExpression q) where T : classnew();

        
/// <summary>
        
/// 按照强类型sql语句查询DataSet
        
/// query dataSet of a entity with a strong type sql 
        
/// </summary>
        
/// <param name="qs"></param>
        
/// <returns></returns>
        DataSet QueryDataSet(params QueryExpression[] qs); //where T : class, new();

    }

关系操作接口

/// <summary>
    
/// 关系操作
    
/// relatin operation to dbo , for the many to many relation
    
/// </summary>
    public interface IDboRelationSession 
    {
        
/// <summary>
        
/// 删除实体,可以指定是否进行关联删除(删除所有自实体)
        
/// delete the reference of the two entities
        
/// </summary>
        
/// <typeparam name="T"></typeparam>
        
/// <param name="o"></param>
        
/// <param name="deleteRef"></param>
        
/// <returns></returns>
        int Delete<T>(T o, bool deleteRef) where T : classnew();

        
/// <summary>
        
/// 获取父实体
        
/// get parent entity of a entity
        
/// </summary>
        
/// <typeparam name="T"></typeparam>
        
/// <param name="obj"></param>
        
/// <returns></returns>
        T GetRef<T>(object obj) where T : classnew();

        
/// <summary>
        
/// 获取子实体列表
        
/// get children entities of a entity
        
/// </summary>
        
/// <typeparam name="T"></typeparam>
        
/// <param name="obj"></param>
        
/// <returns></returns>
        IList<T> GetRefList<T>(object obj) where T : classnew();

        
/// <summary>
        
/// 保存多对多实体关系
        
/// save the reference of the two entities
        
/// </summary>
        
/// <param name="obj1"></param>
        
/// <param name="obj2"></param>
        
/// <returns></returns>
        int SaveRef(object obj1, object obj2);

        
/// <summary>
        
/// 删除多对多实体关系
        
/// delete the reference of the two entities
        
/// </summary>
        
/// <param name="obj1"></param>
        
/// <param name="obj2"></param>
        
/// <returns></returns>
        int DeleteRef(object obj1, object obj2);
 
    }

开始使用DBO

第一步:设计数据库

按照我们的习惯设计数据库,建议使用PowerDesigner功能,利用它的代码生成功能生成实体代码。也可以用其他工具,如CodeSmith。再强调一下:DBO支持的实体是平板数据,实体类属性跟数据表属性一一对应。

,有一个组织机构类:

using DBO.Attributes;
using DBO.QueryLanguage;
using DBO.QueryLanguage.SpecalField;

    [Table("Org")]
    [Relation(typeof(User), RelationMode.OneToMany )]
    class Org
    {
        static public QueryField<Org> __OrgId = new QueryField<Org>("OrgId"); //
查询字段

        static public StringQueryField<Org> __OrgName = new StringQueryField<Org>("OrgName");

        static public IntQueryField<Org> __ParentId = new IntQueryField<Org>("ParentId");
       

        private int _OrgId;
        [PrimaryKey( KeyGenerateMode.Guid )]
        public int OrgId
        {
            get { return _OrgId; }
            set { _OrgId = value; }
        }

        private string _OrgName;

        [Column(Name="OrgName")]
        public string OrgName
        {
            get { return _OrgName; }
            set { _OrgName = value; }
        }

        private string _Location = "l";

        public string Location
        {
            get { return _Location; }
            set { _Location = value; }
        }

        private int? _ParentId;    
       
public int? ParentId //
支持nullable
        {
            get { return _ParentId; }
            set { _ParentId = value; }
        }

        private DateTime _CreateTime = DateTime.Now ;
        public DateTime CreateTime
        {
            get { return _CreateTime; }
            set { _CreateTime = value; }
        }

        private int _ObjectState = 0;
        [NoMap]
        public int ObjectState
        {
            get { return _ObjectState; }
            set { _ObjectState = value; }
        }

    }

从以上类我们可以了解到以下用来配置影射的特性(Attribute)

Table :指定实体类映射到的表名,若没指定则表名跟类名一致

Relation指定跟其他实体的关系,支持 OneToOne , OneToMany ,ManyToOne ,ManyToMany

PrimaryKey : 指定主键字段,支持多个主键,主键生成,模式支持标识,SequenceGuidNone

Column: 配置映射到的列,若无,则列名跟属性名一致。

NoMap:指定此属性不参与映射。

Ref:指定此属性关联到的实体(以上Org类没有体现出来,可以看下面的User类)。

那些 static public QueryField<Org> 是什么呢?

QueryField 这个静态字段写上去之后,就可以按某个字段任意查询了!

第二步:设置连接字符串

数据库连接的配置采用.net2.0中标准的配置:

  <connectionStrings>

    <add name="default" connectionString="data source=(local);packet size=4096;user id=sa;initial catalog=DboExapmle;password=123456" providerName="System.Data.SqlClient" />   

  </connectionStrings>
 

第三步:写调用代码啦

using DBO;
using DBO.QueryLanguage;

IDboSession dboSession = DboFactory.OpenDboSession("defalut"); //打开数据库会话

Org org = new Org();

org.OrgName = "Org1";

dboSession.Insert(org); //插入

dboSession.Delete(org); //再删除

dboSession.Update(org); //修改

Org orgFormDb = dboSession.Get<Org>( 1 ); //按照主键获取一个实体

Org orgFromDb2 = dboSession.Get<Org>(Org.__OrgName == "Org1"); //按条件获取获取一个实体

IList<Org> orgs = dboSession.Query<Org>(Org.__OrgName == "Org1" | Org.__OrgName == "Org2"); //按条件查询

IList<Org> allOrgs = dboSession.LoadAll<Org>(); //加载所有数据

dboSession.DeleteAll<Org>(); //清空表

dboSession.Close(); //关闭数据库会话                                         

DBO高级功能

跨表查询

假设有两个表:部门表 Org 和用户表 UserOrg实体如上,User 实体如下:

using DBO.Attributes;
using DBO.QueryLanguage;
using DBO.QueryLanguage.SpecalField;

[Table("User")]
    class User
    {
        static public StringQueryField<User> __UserName = new StringQueryField<User>("UserName");

        static public QueryField<User> __OrgId = new QueryField<User>("OrgId");

        static public TypeQueryField<User, UserType> __UserType = new TypeQueryField<User, UserType>("UserType");

        static public TypeQueryField<User, int> __Age = new TypeQueryField<User, int>("Age");

        private int _UserId;

        [PrimaryKey]
        public int UserId
        {
            get { return _UserId; }
            set { _UserId = value; }
        }

        private string _UserName;
        public string UserName
        {
            get { return _UserName; }
            set { _UserName = value; }
        }

        private int _Age;
        public int Age
        {
          get { return _Age; }
          set { _Age = value; }
        }

        private int _OrgId;
        [Ref(typeof(Org))]
        public int OrgId
        {
            get { return _OrgId; }
            set { _OrgId = value; }
        }

}

现在有一个页面,需要显示一个用户列表,同时显示出每个用户所属的部门名。可以建一个关联实体

    [Join( typeof(Org) , JoinMode.LeftJoin )] //设置关联信息 
   
class RefOrgUser : User
    {       
       
private string _OrgName;

    [Column(Owner = typeof(Org), DisplayName = "单位名" , DataType=DataType.LargText,MaxLength=50)]
        public string OrgName
        {
            get { return _OrgName; }
            set { _OrgName = value; }
        }
    }

OKRefOrgUser对象拥有了OrgName属性,可以满足页面显示的需要了:

     using DBO;
     using DBO.QueryLanguage;

     IDboSession dboSession = DboFactory.OpenDboSession("defalut"); //打开数据库会话

 IList<RefOrgUser> usersWithOrg = dboSession.Query<RefOrgUser>(Org.__OrgId == 1); //获取部门Id1的所有用户

Sql随意查询

using DBO;
using DBO.QueryLanguage;

QueryExpression expr =

             DboQuery.Select( User.__UserName,Org.__OrgName )

             .From<User>()

             .InnerJoin<Org>().On(User.__OrgId, Org.__OrgId)

             .Where(Org.__OrgId == 2 | Org.__OrgId == 3);

 IList<RefOrgUser> orgs = _session.Query<RefOrgUser>(expr) ;

关联删除

删除单位1和单位1下所有用户

using DBO;
using DBO.QueryLanguage;

IDboSession dboSession = DboFactory.OpenDboSession("defalut"); //打开数据库会话

Org deletedOrg = new Org();

deletedOrg.OrgId = 1;

dboSession.Delete(deletedOrg, true);


  下载dll:下载
 

jianyi0115@163.com

2007-6-4

posted on 2007-06-04 23:24  jianyi  阅读(4995)  评论(38编辑  收藏  举报