在开发ORM之前,先简单的介绍下ORM的基本概念。
对象关系映射(Object Relational Mapping,简称ORM)是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术。 简单的说,ORM是通过使用描述对象和数据库之间映射的元数据,将程序中的对象自动持久化到关系数据库中。本质上就是将数据从一种形式转换到另外 一种形式。
产生渊源
你在DAL中写了很多的方法来读取对象数据,改变状态对象等等任务。而这些代码写起来总是重复的。看看DAL代码,你肯定会看到很多近似的通用的模式。人们就想了,能不能自动化实现DAL呢,其实大部分是可以的,所以ORM的各种工具诞生了,他们会自动为你生成dal的代码。
目前.net平台下比较流行的 ORM 产品有NHibernate,Entity Framework等。 相对于NHibernate这些重量级的ORM产品,对数据库的一张表做关系映射,就必须为其建立一张hbm.xml的映射文件,显得有些繁琐。c#支持自定义特性,对于数据库字段的一些属性关系映射,我们可以通过在Model类(数据库结构关系映射类)的属性上标注自定义特性来抽象描述数据库相关字段。
目标效果预览
数据库表结构:
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using Model.Entities; 6 using System.Data; 7 namespace Model 8 { 9 [Serializable] 10 public class EmpInfoModel : BaseEntity 11 { 12 /// <summary>是否可以修改 13 /// </summary> 14 public const bool isCanMod = false; 15 /// <summary>tableName 16 /// </summary> 17 public const String TableName = "EmpInfo"; 18 public EmpInfoModel() 19 { } 20 21 private string _Id; 22 private string _Name; 23 private int? _isAllMoneyCheck; 24 private Guid? _MyGuid; 25 private Int16? _MySmallint; 26 private bool? _MyBool; 27 private string _Myntext; 28 [DBField(KeyType = DbKeyType.PK)] 29 [DBType(SqlDBType=SqlDbType.NVarChar)] 30 public virtual string Id 31 { 32 set { _Id = value; } 33 get { return _Id; } 34 } 35 36 public string Name 37 { 38 set { _Name = value; } 39 get { return _Name; } 40 } 41 42 43 public int? isAllMoneyCheck 44 { 45 set { _isAllMoneyCheck = value; } 46 get { return _isAllMoneyCheck; } 47 } 48 49 [DBType(SqlDBType = SqlDbType.UniqueIdentifier)] 50 public Guid? MyGuid 51 { 52 set { _MyGuid = value; } 53 get { return _MyGuid; } 54 } 55 56 [DBType(SqlDBType = SqlDbType.SmallInt)] 57 public Int16? MySmallint 58 { 59 set { _MySmallint = value; } 60 get { return _MySmallint; } 61 } 62 63 [DBType(SqlDBType = SqlDbType.Bit)] 64 public bool? MyBool 65 { 66 set { _MyBool = value; } 67 get { return _MyBool; } 68 } 69 [DBType(SqlDBType = SqlDbType.NText)] 70 public string Myntext 71 { 72 set { _Myntext = value; } 73 get { return _Myntext; } 74 } 75 } 76 }
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using Model.Entities; 6 using Model; 7 using DAL.ErpSqlDAL.SqlFactory; 8 using DAL.ErpSqlDAL.SqlFactory.Common; 9 namespace DAL.Data 10 { 11 public class EmpInfoDAL : BaseDAL<EmpInfoModel> 12 { 13 public EmpInfoDAL(DbCmd dbCmd) 14 : base(dbCmd, EmpInfoModel.TableName) 15 { 16 17 } 18 19 public IList<EmpInfoModel> getTopOneList() 20 { 21 return base.GetEntityBySql("select * from EmpInfo where id=1", null); 22 } 23 } 24 }
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using Model.Entities; 6 namespace DAL.ErpSqlDAL.SqlFactory 7 { 8 public class BaseDAL<T> : OperateEntity<T> 9 where T : BaseEntity 10 { 11 private string entityName; 12 13 public BaseDAL(DbCmd dbCmd, string entityName) 14 : base(dbCmd, entityName, typeof(T)) 15 { 16 this.dbCmd = dbCmd; 17 this.entityName = entityName; 18 } 19 20 21 /// <summary>得到一个实体的内容 22 /// </summary> 23 /// <param name="conditionList">条件实体</param> 24 /// <returns></returns> 25 public virtual T GetOneEntity(T conditionList) 26 { 27 try 28 { 29 IList<T> entityList = base.GetEntity(conditionList); 30 if (entityList.Count > 0) 31 return entityList[0]; 32 return null; 33 } 34 catch 35 { 36 throw; 37 } 38 } 39 /// <summary>添加实体 40 /// </summary> 41 /// <param name="entity">要添加的实体</param> 42 /// <returns></returns> 43 public virtual object AddEntity(T entity) 44 { 45 try 46 { 47 IList<T> entityList = new List<T>(); 48 entityList.Add(entity); 49 50 return base.AddEntity(entityList); 51 } 52 catch 53 { 54 throw; 55 } 56 57 } 58 59 /// <summary>根据主键修改实体 60 /// </summary> 61 /// <param name="entity">要修改的内容和包含主键值的实体</param> 62 /// <returns></returns> 63 public virtual int ModEntity(T entity) 64 { 65 try 66 { 67 IList<T> entityList = new List<T>(); 68 entityList.Add(entity); 69 70 return base.ModEntity(entityList); 71 } 72 catch 73 { 74 throw; 75 } 76 } 77 /// <summary>修改实体 78 /// </summary> 79 /// <param name="sourceEntity">要修改的内容</param> 80 /// <param name="conditionEntity">修改的条件</param> 81 /// <returns></returns> 82 public virtual int ModEntity(T sourceEntity, T conditionEntity) 83 { 84 try 85 { 86 IList<T> SourceEntityList = new List<T>(); 87 SourceEntityList.Add(sourceEntity); 88 89 IList<T> conditionEntityList = new List<T>(); 90 conditionEntityList.Add(conditionEntity); 91 92 return base.ModEntity(SourceEntityList, conditionEntityList); 93 } 94 catch 95 { 96 throw; 97 } 98 } 99 100 /// <summary>删除实体 101 /// </summary> 102 /// <param name="entity">删除的条件</param> 103 /// <returns></returns> 104 public virtual int DelEntity(T entity) 105 { 106 try 107 { 108 IList<T> SourceEntityList = new List<T>(); 109 SourceEntityList.Add(entity); 110 111 return base.DelEntity(SourceEntityList); 112 } 113 catch 114 { 115 throw; 116 } 117 } 118 } 119 }
使用:
1 public partial class Test : System.Web.UI.Page 2 { 3 public string connetionString = "server=.;initial catalog=test;UID=sa;PWD=sa123"; 4 protected void Page_Load(object sender, EventArgs e) 5 { 6 if (!IsPostBack) 7 { 8 BindData(); 9 10 } 11 } 12 13 protected void BindData() 14 { 15 DbCmd dbCmd = new DbCmdFactory(connetionString).CreateDbCmd(); 16 IList<EmpInfoModel> list = new EmpInfoDAL(dbCmd).GetEntity(null); 17 GridView1.DataSource = list; 18 GridView1.DataBind(); 19 } 20 21 protected void Button1_Click(object sender, EventArgs e) 22 { 23 DbCmd dbCmd = new DbCmdFactory(connetionString).CreateDbCmd(); 24 25 EmpInfoModel model = new EmpInfoModel(); 26 model.Id = (GridView1.Rows.Count + 1).ToString(); 27 model.Name = "name" + model.Id+@"@!#$%^&*()_+-=<>:""{}|\‘;/.,"; 28 model.isAllMoneyCheck = 1; 29 model.MyGuid = Guid.NewGuid(); 30 model.MySmallint = 2; 31 model.MyBool = true; 32 model.Myntext = "Myntext " + model.Id; 33 new EmpInfoDAL(dbCmd).AddEntity(model); 34 BindData(); 35 } 36 37 protected void Button2_Click(object sender, EventArgs e) 38 { 39 DbCmd dbCmd = new DbCmdFactory(connetionString).CreateDbCmd(); 40 EmpInfoModel model = new EmpInfoModel(); 41 model.Id = ("1").ToString(); 42 43 model.isAllMoneyCheck = 2; 44 model.MyGuid = Guid.NewGuid(); 45 model.MySmallint = 2; 46 model.MyBool = true; 47 new EmpInfoDAL(dbCmd).DelEntity(model); 48 BindData(); 49 } 50 51 protected void Button3_Click(object sender, EventArgs e) 52 { 53 DbCmd dbCmd = new DbCmdFactory(connetionString).CreateDbCmd(); 54 IList<EmpInfoModel> list = new EmpInfoDAL(dbCmd).getTopOneList(); 55 GridView1.DataSource = list; 56 GridView1.DataBind(); 57 } 58 }
通过对Model类属性做自定义特性来映射,数据库字段和程序类型的对应关系,是否为主键,是否外键,是否为虚拟字段等。
在下一篇中将开始研究如何一步一步的构建一个ORM框架。