一直处于纠结的边缘,左右不是,不知何去何从,想写点东西,有不知道写点什么,总是手高眼底,想一大通,做的极少,最终总是浑浑噩噩的锅,什么也没完成。今天受到路过秋天大哥的鼓励,才让我继续我之前未完成的文章些列,在这里先谢过。
在这篇文章主要讲述数据库实体基类对象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类:
{
using System;
using System.Collections.Generic;
using System.Data;
using SAS.ORM.FieldType;
/// <summary>
/// NameSpace :: SAS.ORM
/// 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 " ;
#region 公共字段/属性
/// <summary>
/// 编号
/// </summary>
public MInt Id { get ; set ; }
#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 == null ) return 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来行代码,如果能够真正了解这个数据库实体基类,不先看看前面两篇文章,还是有点难度的。
下面来看看我的业务层调用:
首先介绍下下面实例中所需要用到的两个表(Note/随笔表,NoteTag/随笔标签表)的字段以及实体类的代码:
随笔表结构/实体类代码
{
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 { get ; set ; }
public MString Body { get ; set ; }
public MInt CreateBy { get ; set ; }
public MDateTime CreateTime { get ; set ; }
public MInt HitCount { get ; set ; }
public MDateTime LastModTime { get ; set ; }
public MInt LastReplyBy { get ; set ; }
public MInt LastReplyTime { get ; set ; }
public MInt ReplyCount { get ; set ; }
public MInt SiteTypeId { get ; set ; }
public MInt Support { get ; set ; }
public MInt TagId { get ; set ; }
public MString Title { get ; set ; }
#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
}
}
随笔标签表结构/实体类代码
{
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(人员招募中...)