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

 

ExpandedBlockStart.gif 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 {  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来行代码,如果能够真正了解这个数据库实体基类,不先看看前面两篇文章,还是有点难度的。

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

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

 

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

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

     随笔表结构/实体类代码

   

   

ExpandedBlockStart.gif 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 {  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
    }
}

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

 

ExpandedBlockStart.gif 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(人员招募中...)  

 

posted on 2011-07-24 19:52 Juvy 阅读( ...) 评论( ...) 编辑 收藏

转载于:https://www.cnblogs.com/Juvy/archive/2011/07/24/2115564.html

最简单的dll并不比c的helloworld难,只要一个DllMain函数即可,包含objbase.h头文件(支持COM技术的一个头文件)。若你觉得这个头文件名字难记,那么用windows.H也可以。源代码如下:dll_nolib.cpp #include #include BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwReason, void* lpReserved) { HANDLE g_hModule; switch(dwReason) { case DLL_PROCESS_ATTACH: cout<<"Dll is attached!"<<endl; g_hModule = (HINSTANCE)hModule; break; case DLL_PROCESS_DETACH: cout<<"Dll is detached!"<<endl; g_hModule=NULL; break; } return true; } 其中DllMain是每个dll的入口函数,如同c的main函数一样。DllMain带有个参数,hModule表示本dll的实例句柄(听不懂就不理它,写过windows程序的自然懂),dwReason表示dll当前所处的状态,例如DLL_PROCESS_ATTACH表示dll刚刚被加载到一个进程中,DLL_PROCESS_DETACH表示dll刚刚从一个进程中卸载。当然还有表示加载到线程中和从线程中卸载的状态,这里省略。最后一个参数是一个保留参数(目前和dll的一些状态相关,但是很少使用)。 从上面的程序可以看出,当dll被加载到一个进程中时,dll打印"Dll is attached!"语句;当dll从进程中卸载时,打印"Dll is detached!"语句。 编译dll需要以下两条命令: cl /c dll_nolib.cpp 这条命令会将cpp编译为obj文件,若不使用/c参数则cl还会试图继obj链接为exe,但是这里是一个dll,没有main函数,因此会报错。不要紧,继使用链接命令。 Link /dll dll_nolib.obj 这条命令会生成dll_nolib.dll。 注意,因为编译命令比较简单,所以本文不讨论nmake,有兴趣的可以使用nmake,或者写个bat批处理来编译链接dll。 加载DLL(显式调用)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值