zoukankan      html  css  js  c++  java
  • 支持差异数据保存的数据库实体类设计(三)(续) ——基类抽象ObjBase的构建以及子类实现

    一直处于纠结的边缘,左右不是,不知何去何从,想写点东西,有不知道写点什么,总是手高眼底,想一大通,做的极少,最终总是浑浑噩噩的锅,什么也没完成。今天受到路过秋天大哥的鼓励,才让我继续我之前未完成的文章些列,在这里先谢过。

    在这篇文章主要讲述数据库实体基类对象ObjBase的构建,首先来一张图片,该图片展示了这套数据库实体所需要的所有类结构:

    FieldType目录:用于存放所有数据库实体属性类型对象(其中FieldTypeBase为实体属性类型基类),里面的具体细节在本系列的第一篇和第二篇文章中都已经讲述过,在这里就不多讲了;

    DalAgent.cs:该类是一个静态类,主要包含一些对象的数据库操作的公共方法;

    ObjBase.cs:该类只有1个Id属性,也就是我们这篇文章的主角了,稍后详细讲解;

    ObjFactoryBase:对象数据库操作类基类;

    ObjNamedBase.cs:该类继承自ObjBase,主要有3个属性:Name,Description,SortOrder,作为所有包含Name/Description信息的对象的基类,SortOrder属性的存在主要是为了排序功能。

    ObjTypeBase.cs:该类继承自ObjNamedBase,有2个属性:ObjTypeId,DataGroupId,作为所有包含“类别”信息的对象的基类,DataGroupId用于存放数据组编号,用于对象授权访问功能。

    下面进入本文主角:ObjBase类:

    View Code
    namespace SAS.ORM
    {
        
    using System;
        
    using System.Collections.Generic;
        
    using System.Data;
        
    using SAS.ORM.FieldType;

        
    /// <summary>
        
    /// NameSpace :: SAS.ORM
        /// Creater :: ZhouWei
        
    /// Create Time :: 2011-5-18 0:52:13
        
    /// </summary>
        public abstract class ObjBase
        {
            /// <summary>
            
    /// 对象所有属性集合
            
    /// </summary>
            internal Dictionary<string, FieldTypeBase> DicField;

            
    #region 数据库字段名

            
    /// <summary>
            
    /// 数据库列名
            
    /// </summary>
            public static string ID = "ID";
     
         #endregion

            
    #region 公共字段/属性

            
    /// <summary>
            
    /// 编号
            
    /// </summary>
            public MInt Id { getset; }

            
    #endregion

            
    #region 构造函数

            
    public ObjBase() { }

            
    public ObjBase(DataRow row)
            {
                
    //初始化对象
                this.FillObject(row);
            }

            
    #endregion

            
    #region  继承可见方法

            
    /// <summary>
            
    /// 将字段添加到列表集合中
            
    /// </summary>
            
    /// <param name="field"></param>
            protected void AddField(FieldTypeBase field)
            {
                
    this.DicField.Add(field.ColumnName, field);
            }

            
    /// <summary>
            
    /// 获取DataRow指定列的值,如果找不到指定列,则返回DBNull.Value
            
    /// 以满足当只查询对象的某些列的时候。
            
    /// </summary>
            
    /// <param name="row"></param>
            
    /// <param name="fieldName"></param>
            
    /// <returns></returns>
            protected object GetFieldValue(DataRow row, ref string fieldName)
            {
                
    if (!row.Table.Columns.Contains(fieldName)) return null;
                
    return row[fieldName];
            }
             
            
    #endregion

            
    #region 公共方法/属性

            
    /// <summary>
            
    /// 通过DataRow进行对象初始化
            
    /// </summary>
            
    /// <param name="row">DataRow</param>
            public virtual void FillObject(DataRow row)
            {
                
    //初始化属性集合
                DicField = new Dictionary<string, FieldTypeBase>();

                
    //初始化属性值
                if (row == null)
                {
                    
    this.Id = new MInt(ref ID, 0);
                }
                
    else
                {
                    
    this.Id = new MInt(ref ID, this.GetFieldValue(row, ref ID));
                }

                
    //添加属性到集合
                this.AddField(this.Id);
            }

            
    /// <summary>
            
    /// 通过DataRow进行对象初始化, 用于关联对象的填充
            
    /// </summary>
            
    /// <param name="row">DataRow</param>
            public virtual void FillRelationObject(DataRow row)
            {
                
    this.FillObject(row);
            }

            
    /// <summary>
            
    /// 根据列名获取属性值
            
    /// </summary>
            
    /// <param name="filedName">字段名</param>
            
    /// <returns></returns>
            public object GetField(string filedName)
            {
                
    if (DicField == nullreturn string.Empty;
                
    if (DicField.ContainsKey(filedName)) return this.DicField[filedName];
                
    return string.Empty;
            }

            
    /// <summary>
            
    /// 保存this
            
    /// </summary>
            
    /// <returns></returns>
            public virtual bool Save()
            {
                
    return DalAgent.Save(this);
            }

            
    /// <summary>
            
    /// 删除this
            
    /// </summary>
            
    /// <returns></returns>
            public virtual bool Delete()
            {
                
    return DalAgent.Delete(this);
            }

            
    /// <summary>
            
    /// 数据库表名
            
    /// </summary>
            public abstract string TableName { get; }

            
    #endregion
        }
    }

     该ObjBase基类主要包括以下内容

    1、一个包内字段DicField,用于装载实体对象的所有属性(主要用于保存或者更新对象时的遍历操作)

    2、1个静态字段,ID;

    3、1个属性(数据库字段)Id,也就说,应用该ORM的所有数据库实体对象都必须有一个字段“Id";

    4、2个构造函数,一个是空构造(空构造的时候,实体类内部所有属性-数据库字段的值都为null,在该基类中就一个Id属性),一个是DataRow对象构造(将DataRow对象中的Id列的值填充到实体类的Id属性中);

    5、继承可见方法:protected void AddField(FieldTypeBase field);该方法有一个FieldTypeBase参数,功能是将该属性添加到DicField中;

                                  protected object GetFieldValue(DataRow row, ref string fieldName);该方法有两个参数,功能是将在DataRow对象找指定列名的单元格的值;

    6、公共方法/属性:public virtual void FillObject(DataRow row);//填充对象
                    public virtual void FillRelationObject(DataRow row);//填充对象,主要用于有关联表查询的时候的填充,具体实现在子类中重写
                    public object GetField(string filedName);//根据数据库列名,获取该列的值,也是在关联表查询中用到的,因为在一般实体表查询的时候,通过属性名即可获取属性值。
                    public virtual bool Save();//保存对象
                    public virtual bool Delete();//删除对象
                    public abstract string TableName { get; }//这个字段的存在主要便于如下调用,obj.TableName。在子类中还会有一个静态字段TABLENAME,主要便于如下调用ObjClass.TABLENAME;

    这个数据库实体基类的设计一路下来150来行代码,如果能够真正了解这个数据库实体基类,不先看看前面两篇文章,还是有点难度的。

    1.支持差异数据保存的数据库实体类设计——处女作

    2.支持差异数据保存的数据库实体类设计(二)(续)

    下面来看看我的业务层调用:

         首先介绍下下面实例中所需要用到的两个表(Note/随笔表,NoteTag/随笔标签表)的字段以及实体类的代码:

         随笔表结构/实体类代码

       

       

    View Code
    namespace Blog.BLL.Data
    {
        
    using System.Data;
        
    using SAS.ORM;
        
    using SAS.ORM.FieldType;
        
    /// <summary>
        
    /// MNote对象实体类
        
    /// </summary>
        public class Note : ObjBase
        {
            
    #region 表名、字段名

            
    public static string TABLENAME = "MNOTE";

            
    public static string AGAINST = "AGAINST";
            
    public static string BODY = "BODY";
            
    public static string CREATEBY = "CREATEBY";
            
    public static string CREATETIME = "CREATETIME";
            
    public static string HITCOUNT = "HITCOUNT";
            
    public static string LASTMODTIME = "LASTMODTIME";
            
    public static string LASTREPLYBY = "LASTREPLYBY";
            
    public static string LASTREPLYTIME = "LASTREPLYTIME";
            
    public static string REPLYCOUNT = "REPLYCOUNT";
            
    public static string SITETYPEID = "SITETYPEID";
            
    public static string SUPPORT = "SUPPORT";
            
    public static string TAGID = "TAGID";
            
    public static string TITLE = "TITLE";
            
    public static string TAGNAME = "TAGNAME";

            
    #endregion

            
    #region 公共属性

            
    public override string TableName { get { return TABLENAME; } }
            
    public MInt Against { getset; }
            
    public MString Body { getset; }
            
    public MInt CreateBy { getset; }
            
    public MDateTime CreateTime { getset; }
            
    public MInt HitCount { getset; }
            
    public MDateTime LastModTime { getset; }
            
    public MInt LastReplyBy { getset; }
            
    public MInt LastReplyTime { getset; }
            
    public MInt ReplyCount { getset; }
            
    public MInt SiteTypeId { getset; }
            
    public MInt Support { getset; }
            
    public MInt TagId { getset; }
            
    public MString Title { getset; }

            
    #endregion

            
    #region 构造函数

            
    public Note() { }

            
    public Note(DataRow row)
            {
                
    this.FillObject(row);
            }

            
    #endregion

            
    #region 其他方法

            
    /// <summary>
            
    /// 通过DataRow进行对象初始化
            
    /// </summary>
            
    /// <param name="row">row</param>
            public override void FillObject(DataRow row)
            {
                
    base.FillObject(row);

                
    //初始化属性值
                if (row == null)
                {
                    
    this.Against = new MInt(ref AGAINST);
                    
    this.Body = new MString(ref BODY);
                    
    this.CreateBy = new MInt(ref CREATEBY);
                    
    this.CreateTime = new MDateTime(ref CREATETIME);
                    
    this.HitCount = new MInt(ref HITCOUNT);
                    
    this.LastModTime = new MDateTime(ref LASTMODTIME);
                    
    this.LastReplyBy = new MInt(ref LASTREPLYBY);
                    
    this.LastReplyTime = new MInt(ref LASTREPLYTIME);
                    
    this.ReplyCount = new MInt(ref REPLYCOUNT);
                    
    this.SiteTypeId = new MInt(ref SITETYPEID);
                    
    this.Support = new MInt(ref SUPPORT);
                    
    this.TagId = new MInt(ref TAGID);
                    
    this.Title = new MString(ref TITLE);
                }
                
    else
                {
                    
    this.Against = new MInt(ref AGAINST, this.GetFieldValue(row, ref AGAINST));
                    
    this.Body = new MString(ref BODY, this.GetFieldValue(row, ref BODY));
                    
    this.CreateBy = new MInt(ref CREATEBY, this.GetFieldValue(row, ref CREATEBY));
                    
    this.CreateTime = new MDateTime(ref CREATETIME, this.GetFieldValue(row, ref CREATETIME));
                    
    this.HitCount = new MInt(ref HITCOUNT, this.GetFieldValue(row, ref HITCOUNT));
                    
    this.LastModTime = new MDateTime(ref LASTMODTIME, this.GetFieldValue(row, ref LASTMODTIME));
                    
    this.LastReplyBy = new MInt(ref LASTREPLYBY, this.GetFieldValue(row, ref LASTREPLYBY));
                    
    this.LastReplyTime = new MInt(ref LASTREPLYTIME, this.GetFieldValue(row, ref LASTREPLYTIME));
                    
    this.ReplyCount = new MInt(ref REPLYCOUNT, this.GetFieldValue(row, ref REPLYCOUNT));
                    
    this.SiteTypeId = new MInt(ref SITETYPEID, this.GetFieldValue(row, ref SITETYPEID));
                    
    this.Support = new MInt(ref SUPPORT, this.GetFieldValue(row, ref SUPPORT));
                    
    this.TagId = new MInt(ref TAGID, this.GetFieldValue(row, ref TAGID));
                    
    this.Title = new MString(ref TITLE, this.GetFieldValue(row, ref TITLE));
                }

                
    //添加属性到集合
                this.AddField(this.Against);
                
    this.AddField(this.Body);
                
    this.AddField(this.CreateBy);
                
    this.AddField(this.CreateTime);
                
    this.AddField(this.HitCount);
                
    this.AddField(this.LastModTime);
                
    this.AddField(this.LastReplyBy);
                
    this.AddField(this.LastReplyTime);
                
    this.AddField(this.ReplyCount);
                
    this.AddField(this.SiteTypeId);
                
    this.AddField(this.Support);
                
    this.AddField(this.TagId);
                
    this.AddField(this.Title);
            }

            
    /// <summary>
            
    /// 通过DataRow进行对象初始化, 用于关联对象的填充
            
    /// </summary>
            
    /// <param name="row">DataRow</param>
            public override void FillRelationObject(DataRow row)
            {
                
    this.FillObject(row);

                MString obj;
                
    object o = this.GetFieldValue(row, ref TAGNAME);
                
    if (o != null)
                {
                    obj 
    = new MString(ref TAGNAME, o);
                    obj.NeedSave 
    = false;
                    
    this.AddField(obj);
                }
            }

            
    #endregion
        }
    }

         随笔标签表结构/实体类代码  

    View Code
    namespace Blog.BLL.Data
    {
        
    using System.Data;
        
    using SAS.ORM;
        
    using SAS.ORM.FieldType;
        
    /// <summary>
        
    /// NoteTag对象实体类
        
    /// </summary>
        public class NoteTag : ObjNamedBase
        {
            
    #region 表名、字段名

            
    public static string TABLENAME = "NOTETAG";


            
    #endregion

            
    #region 公共属性

            
    public override string TableName { get { return TABLENAME; } }

            
    #endregion

            
    #region 构造函数

            
    public NoteTag() { }

            
    public NoteTag(DataRow row)
            {
                
    this.FillObject(row);
            }

            /// <summary>
            
    /// 通过DataRow进行对象初始化, 用于关联对象的填充
            
    /// </summary>
            
    /// <param name="row">DataRow</param>
            public override void FillObject(DataRow row)
            {
                base.FillObject(row);

      }

            
    #endregion
        }
    }

    1、获取数据列表对象:

         static string _SQL_GetNoteList = "SELECT n.*, nt.Name as TagName from [Note] n, NoteTag nt where n.TagId = nt.Id";

         //获取关联信息对象列表

         IList<Note> list = DalAgent.GetListRelationObject<Note>(_SQL_GetNoteList,  null);    

         //获取自身信息对象列表

         IList<Note> list = DalAgent.GetListObject<Note>("select * from [Note] where Id < 100", null);

         //获取自身信息全部对象列表

         IList<Note> list = DalAgent.GetListAll<Note>(Note.TABLENAME);

    2、实体对象属性值获取

          Note n = list[0]; (该list由DalAgent.GetListRelationObject<Note>(_SQL_GetNoteList, ref pi, orderBy, null)方法获取

         1)、自身属性值获取:n.Title, n.Body...

         2)、关联表属性值获取:n.GetField(Note.TAGNAME).ToString();其中“Note.TAGNAME”为关联表字段,从查询语句中可以看到。 

    3、实体对象的插入

      Note note = new Note();//构造一个空对象

      note.Fill(null);//利用一个空DataRow对象来填充note,如果不进行这一步,note的所有属性都为null,导致在调用note.Id的时候会直接报错。
      note.Id.SetValue(0);//然后给Id赋值
      note.Title.SetValue(title + i.ToString());//给Title赋值
      note.TagId.SetValue(tagId);//给TagId赋值
      note.CreateTime.SetValue(DateTime.Now);//给CreateTime赋值
      note.Save();//插入 

    4、实体对象的保存

      Note note = DalAgent.GetObjectById<Note>(Note.TableName, 1);//获取Id为1的Note对象

      note.CreateTime.SetValue(DateTime.Now);//给CreateTime重新赋值
      note.Save();//更新数据库

    5、实体对象的删除

      Note note = DalAgent.GetObjectById<Note>(Note.TableName, 1);//获取Id为1的Note对象

           note.Delete();//删除对象

    这篇文章到这里就基本上就完成了,在发布文章的过程中,发现实体类的部分代码有一些小问题而中止(一心跑去改代码去了),导致有些人看到了不全的文章,在此表示道歉。

     ASP.NET开发技术交流群: 67511751(人员招募中...)  

  • 相关阅读:
    高精度 模板
    《图论》邻接表
    模板整理
    H
    C
    同余定理的应用(处理大数
    H
    1153: 简易版最长序列
    1152: 二分搜索
    1151: 大整数加法(正数)
  • 原文地址:https://www.cnblogs.com/Juvy/p/2115564.html
Copyright © 2011-2022 走看看