• DBO 一个新的轮子


    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

  • 相关阅读:
    ubuntu18.04安装ssh服务
    跳转
    【WinForm】—窗体之间传值的几种方式
    使用jQuery完成复选框的全选和全不选
    VS2015下载安装随笔记录
    关于c#数据类型,类型转换,变量,常量,转义符。
    浅谈表单同步提交和异步提交
    form表单提交和跳转
    2019年8月19日矩阵
    C# WinForm快捷键设置技巧
  • 原文地址:https://www.cnblogs.com/jianyi0115/p/771325.html
Copyright © 2020-2023  润新知