自己动手写个orm实现(1)
最近公司项目开动了,出于各种考虑还是相对保守的采用 .NET 2.0 + 企业库 + SQLSERVER的大体框架.
为了封装单个实体对象的CRUD操作,遂自己动手写了一个orm实现的工具类库.
-------------------------------------------------------------------------------------------------------
首先,我们声明一个实体接口 IEntity{
intID{get;set;}
boolIsPersisted{get;}
IEntity{get;}
}根据图示,IEntity接口实现ICloneable接口,并且有三个属性
ID:对应每个实体类型所对应的数据库表的主键ID(有一个前言约定:所有表的主键id均为自增标识)
IsPersisted:指示对象是否已持久化(对应到数据库表的一条记录)
Raw:返回对象实例的已持久化的原始状态
有了实体,如何mapping到具体哪个数据表呢?
"约定优于配置", 因此我们直接使用Attribute来实现{
privatestring_tableName;
publicstringTableName
{
get{return_tableName;}
set{_tableName=value;}
}
publicEntityMappingAttribute(stringtableName)
{
TableName=tableName;
}
}同理,为了建立实体Property到数据表字段的对应关系我们新建PropertyMappingAttribute类
{
privatestring_fieldName;
publicstringFieldName
{
get{return_fieldName;}
set{_fieldName=value;}
}
publicPropertyMappingAttribute(){}
publicPropertyMappingAttribute(stringfieldName)
{
FieldName=fieldName;
}
}经过上述处理,一个十分简单的面向对象实体(Object)到关系型数据表(Relationship)的映射(Mapping)就已经声明完毕了.
既然前面声明了IEntity接口, 理所当然的我们应该实现它{
privateIEntity_raw;
privateint_id;
privatebool_isPersisted=false;
IEntityMembers#regionIEntityMembers
/**////<summary>
///ID
///</summary>
publicvirtualintID
{
get{return_id;}
set{_id=value;}
}
publicvirtualIEntityRaw
{
get{return_raw;}
protectedset{_raw=value;}
}
/**////<summary>
///该对象是否已持久化
///</summary>
publicvirtualboolIsPersisted
{
get{return_isPersisted;}
protectedset{_isPersisted=value;}
}
#endregion
ICloneableMembers#regionICloneableMembers
publicobjectClone()
{
Typetype=this.GetType();
objectobj=Activator.CreateInstance(type);
foreach(PropertyInfopintype.GetProperties())
{
objectvalue=p.GetValue(this,null);
p.SetValue(obj,value,null);
}
returnobj;
}
#endregion
}由于IEntity实现了ICloneable接口,实际上肩负重任的抽象类EntityBase需要实现两个接口.
因为我们不能向外界暴露设置实体是否持久化和原始状态的信息的设置器,我们把set修饰为protected.
而实现ICloneable比较简单,就是利用反射构造出一个当前实体对象实例的拷贝.
基础工作差不多了, 让我们我们新建一个User[EntityMapping("t_user")]
publicclassUser:EntityBase
{
[PropertyMapping]
publicstringName{get;set;}
publicstringHello
{