支持差异数据保存的数据库实体类设计(三)(续) ——基类抽象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(人员招募中...)  

原文地址:https://www.cnblogs.com/Juvy/p/2115564.html