自己动手写个ORM 实现(1)

最近公司项目开动了,出于各种考虑还是相对保守的采用 .NET 2.0 + 企业库 + SQLSERVER的大体框架.

为了封装单个实体对象的CRUD操作,遂自己动手写了一个orm实现的工具类库.
-------------------------------------------------------------------------------------------------------
首先,我们声明一个实体接口  IEntity

public interface IEntity : ICloneable
{
    
int ID getset; }
    
bool IsPersisted get; }
    IEntity 
get; }
}




根据图示, IEntity接口实现ICloneable接口, 并且有三个属性
ID : 对应每个实体类型所对应的数据库表的主键ID  (有一个前言约定: 所有表的主键id均为自增标识)
IsPersisted : 指示对象是否已持久化(对应到数据库表的一条记录)
Raw : 返回对象实例的已持久化的原始状态

有了实体,如何mapping到具体哪个数据表呢 ?
"约定优于配置", 因此我们直接使用Attribute来实现

public class EntityMappingAttribute : Attribute
    
{
        
private string _tableName;        
        
public string TableName
        
{
            
get return _tableName; }
            
set { _tableName = value; }
        }
        

        
public EntityMappingAttribute(string tableName)
        
{
            TableName 
= tableName;
        }


    }

同理,为了建立实体Property到数据表字段的对应关系我们新建PropertyMappingAttribute类
public class PropertyMappingAttribute : Attribute
    
{
        
private string _fieldName;

        
public string FieldName
        
{
            
get return _fieldName; }
            
set { _fieldName = value; }
        }


        
public PropertyMappingAttribute() { }

        
public PropertyMappingAttribute(string fieldName)
        
{
            FieldName 
= fieldName;
        }


    }

经过上述处理, 一个十分简单的面向对象实体(Object)到关系型数据表(Relationship)的映射(Mapping)就已经声明完毕了.


既然前面声明了IEntity接口, 理所当然的我们应该实现它
public abstract class EntityBase : IEntity
    
{
        
private IEntity _raw;
        
private int _id;
        
private bool _isPersisted = false;

        
IEntity Members


        
ICloneable Members
    }

由于IEntity 实现了ICloneable接口, 实际上肩负重任的抽象类EntityBase需要实现两个接口.
因为我们不能向外界暴露设置实体是否持久化和原始状态的信息的设置器, 我们把set修饰为protected.
而实现ICloneable比较简单,就是利用反射构造出一个当前实体对象实例的拷贝.


基础工作差不多了, 让我们我们新建一个User
[Serializable]
[EntityMapping(
"t_user")]
public class User : EntityBase
{
    [PropertyMapping]
    
public string Name get;set;}
    
    
public string Hello 
    

        
get return "hello, I am "+Name;}
    }
 
}
从前面的介绍可以知道,存在一个t_user表(字段有id,name),我们用User类来对应.

东西已经有了,如何使用是关键. 第一步我们要实现的是简单的Crud操作, 先声明一下管理这些操作的接口 IEntityManager
public interface IEntityManager
    
{
        T Create
<T>(T t) where T : IEntity;
        
void Update<T>(T t) where T : IEntity;
        T Load
<T>(int id) where T : IEntity;
        
void Delete<T>(int id) where T : IEntity;
        List
<T> LoadAll<T>() where T : IEntity;
    }


在这里我们声明了几个泛型方法用来实现管理实体对象,并且约束其传入的参数必须实现我们上面声明IEntity接口

--------------------------------------------------
下一节,我们将完成IEntityManager是如何去实现管理实体的功能.

posted on 2008-05-23 17:26  yyliuliang  阅读(4541)  评论(32编辑  收藏  举报

导航