基于net6的简单ORM编码实现
本文手把手实现一个简单的ORM框架,仅作为学习,免去多余的功能,力求简单。本文使用VS2022,数据库是MS SQL Server。
一、 什么是ORM?
ORM即对象关系映射,英文叫:Object-Relational Mapping。它的作用是在将关系型数据库中的数据表和业务实体类之间作一个映射。ORM使得我们只需操作对象的方法和属性,即可完成对数据库的增删查改,避免了与复杂繁琐的SQL语句打交道。
ORM隐藏了访问数据库的细节,使得新手可以简单地操作数据库,但同时有些好学的技术人员希望了解ORM到底是怎么实现的。
二、 ORM实现原理
我们都知道,操作数据库需要编写SQL语句,SQL语句有增删查改事务存储过程等。SQL语句都有固定的要求格式,而语句中的字段则是根据数据表字段的不同而不同。
(1)定义一个类,此类的属性与数据表的字段一一对应。
(2)利用C#中的反射,获得类的字段名称,类名等信息。
(3)当要向数据库新增数据时,将字段名、类名组装成SQL语句,再连接数据库进行执行,其他删除、查询、修改的操作也类似。
三、 准备工作-创建数据表scheduleList
本实例使用VS2022,基于NET6,microsoft SQL Server 2012。新建一数据库,名称随意,并新建一数据表,名称scheduleList。有三个字段ID、title、和createTime,分别表示是主键ID,标题和创建时间。
四、定义scheduleList类
定义一个类,名为scheduleList。代码如下: /** *scheduleList.cs * *Ver 变更日期 作者 *V1.0 2022-03-28 12:33:21 * *VX:lwdred QQ:463183376 */ using System; namespace Model.schedule { /// /// /// //[Serializable] [EntityHelper.Model.Property("scheduleList")] public class scheduleList { private long _id=0; /// /// ID /// [EntityHelper.Model.Property(EntityHelper.Model.ColumnKeyType.Identity)] public long id { set{ _id=value;} get{return _id;} } private string _title=string.Empty; /// /// 标题 /// public string title { set{ _title=value;} get{return _title;} } private DateTime _createtime=DateTime.Now; /// /// 创建时间 /// public DateTime createTime { set{ _createtime=value;} get{return _createtime;} } } }
类scheduleList,有三个字段ID、title、和createTime,分别含义是主键ID,标题和创建时间。为简单起见,本ORM并没有作别名设计,所以注意三个字段名与数据库表中的字段需一摸一样。
其中以下语句是用来标记该字段ID作为主键。 [EntityHelper.Model.Property(EntityHelper.Model.ColumnKeyType.Identity)]
以下语句用来标记当前类对应的数据表名是:scheduleList。 [EntityHelper.Model.Property("scheduleList")]
五、通过反射从类信息中获得字段名称和数据表名称 //定义实体 scheduleList schedule = new scheduleList(); schedule.id= 1; schedule.title = "标题"; schedule.createTime = DateTime.Now;
使用C#中的反射(System.Reflection),从实体中获得字段列表,将字段一一填充至SQL语句中,SQL语句就组装好了。
//通过反射获得实体字段 Type type = typeof(scheduleList); PropertyInfo[] pis = type.GetProperties(); foreach (PropertyInfo pi in pis) { Console.WriteLine(pi.Name); }
通过反射获得数据表的表名 PropertyAttribute property = (PropertyAttribute)(type.GetCustomAttributes(typeof(PropertyAttribute), false)[0]); Console.WriteLine(property.tableName);
新增操作的完整代码: #region 新增 /// /// 新增 /// /// 实体类型 /// 实体数据 /// 主键自增时:false、显式插入主键值:ture /// 连接字符串 /// public bool Insert(T model, bool isIncludeKeyColumn, string connString) where T : class { Type type = typeof(T); if (type == null) { return false; } PropertyInfo[] pis = type.GetProperties(); if (pis == null || pis.Length <= 0) { return false; } //获取表名 string tableName = GetTableName(type); if (string.IsNullOrEmpty(tableName)) { return false; } List columns = null; if (isIncludeKeyColumn == false) { //主键自增 columns = GetTableColumnsList(pis, ColumnKeyType.Identity | ColumnKeyType.Extend|ColumnKeyType.WidthoutAdd); } else { //显式插入主键值 columns = GetTableColumnsList(pis, ColumnKeyType.Extend | ColumnKeyType.WidthoutAdd); } if (columns == null || columns.Count <= 0) { return false; } //生成INSERT语句 StringBuilder sqlText = new StringBuilder(); sqlText.Append("INSERT INTO "); sqlText.Append(tableName); sqlText.Append(" ("); for (int i = 0; i < columns.Count; i++) { sqlText.Append(columns[i]); if (i < columns.Count - 1) { sqlText.Append(","); } } sqlText.Append(") VALUES ("); for (int i = 0; i < columns.Count; i++) { sqlText.AppendFormat("@{0}", columns[i]); if (i < columns.Count - 1) { sqlText.Append(","); } } sqlText.Append(");"); SqlParameter[] paras = new SqlParameter[columns.Count]; for (int i = 0; i < paras.Length; i++) { PropertyInfo propertyInfo = type.GetProperty(columns[i]); paras[i] = new SqlParameter(columns[i], GetMySqlDbType(propertyInfo.PropertyType), -1); paras[i].Value = propertyInfo.GetValue(model, null); } return SqlHelper.ExecuteNonQuery(connString, sqlText.ToString(), paras); } #endregion
其它操作不再一一列出。
我已将代码上传,下载码是: 4DACA2657F
下载码是啥?如何下载=》三味书屋-基于net6的简单ORM编码实现
欧冠16强出炉英德各4队入围,意甲三雄晋级,西甲仅皇马独苗北京时间11月3日凌晨,欧冠小组赛最后一个比赛日结束争夺。在这个比赛日过后,本赛季进入欧冠淘汰赛阶段的16支球队全部产生。本赛季欧冠小组赛阶段英超4支球队全部突围,德甲5支球队有4
10月3日NBA常规赛直播奇才vs76人北京时间11月3日上午6点20222023赛季NBA常规赛继续进行76人主场迎战奇才(戳我观赛)本赛季到目前为止,76人队取得了4胜4负的战绩,在东部排名第六。三位核心球员乔尔尔比
斯诺克3席4强出炉!小特轰61,会师塞尔比,赵心童搭末班车?今晨,2022年斯诺克冠中冠结束第3比赛日,已决出3席4强。卫冕冠军特鲁姆普气势如虹,打出2连胜会师塞尔比,8强战轰出61打停马克艾伦制造最悬殊比分。抽到上上签的赵心童今晚出战,全
十一月一日悼十一月一日余不愿泣,悲却难宣突闻噩耗,愕然哀哉!生于疫情,夭折于关口祖国之花朵,未曾绽放却已凋零父母之勇士,可再无相见之日病毒当下,生之艰苦,活着更难精准防疫,国之大爱,为国为民
人之歌人之歌文聂西峰一撇一捺是个人,相互支撑是真人。相亲相爱是家人,可敬可佩是军人。老朋旧友是故人,施惠救助是恩人。多做好事是善人,帮忙扶持是贵人。才干双全是能人,巧夺天工是匠人。指点江
世界向左,我向右当我打开屏幕在文档上开始尝试敲下第一个字时,我并不知道自己要写什么,或者想要表达些什么。正如我不知道下一秒这个世界会发生什么事情我的生命会发生什么变化一样。我只是习惯性地想写点东西
人生无常不要仅停留在感叹人生无常(人生篆书)无常一词出自佛教著名的三法印诸行无常,诸法无我,涅槃寂静一切事物生灭不定,一切事物皆无主宰,超越生死烦恼境界为清静永恒。三法印是佛教对宇宙间事物总的解释,也是判
三观超正的文案1。做喜欢的事情,奔赴真实简单的活。2。提升迎合别要有的多。3。命中的不期遇都是你努中的惊喜。4。没有彩排,每个细节都是现场直播。5。相信相信切,美好的明天在等着你。6。海纳百川,
一个人很穷时,停止内卷,就翻身了每天一大早,爬起来,做一份自己并不喜欢的工作。生活很难,由不得你睡个懒觉。我们每天都在付出,但是生活始终没有起色。你想要做点什么,会发现到处人满为患每一条上升的通道,都是千军万马的
加强网暴治理,预警预防要给力日前,中央网信办印发关于切实加强网络暴力治理的通知。通知提出,网络暴力针对个人集中发布侮辱谩骂造谣诽谤侵犯隐私等违法信息及其他不友善信息,侵害他人合法权益,扰乱正常网络秩序。要建立
用中阿双语讲好中国故事(侨胞说祖国在我心中(74))图为马强在中国共产党第二十次全国代表大会新闻中心。(受访者供图)在海外有这样一群华媒人,他们致力于用当地民众喜闻乐见的方式,讲述中国故事,展现日新月异的中国面貌。埃及中国周报社社长