.Net 自己写个简单的 半 ORM (练手)
ORM 大家都知道, .Net 是EF 还有一些其他的ORM 从JAVA 中移植过来的 有 , 大神自己写的也有
不管ORM 提供什么附加的 乱七八糟的功能
但是 最主要的 还是 关系映射 的事情。
我自己一直在使用ORMDapper 这个很小的ORM 第一次看到这个ORM 是通过一个帖子中 有人搞了个常见ORM 效率排行榜 ,自己也试了试 然后就看上 ORMDapper 这个了
这是把轻量级发挥到极致了! 只有一个 96KB 的 一个Class 文件。其中还有很多是空格和注释信息。
最近在学习研究JAVA 觉得JAVA 比.NET 有趣点。 也为了 以后 .NET 不行了 还能弄JAVA
直接上代码:
        private static string ConnectionString = "**";
        /// <summary>
        ///  更新数据   没有sql参数就直接执行
        /// </summary>
        /// <param name="sql"> 需要执行的 sql </param>
        /// <param name="o">传递的实体类对象 要求该类中字段必须和 sql参数名称一致 不区分大小写 </param>
        /// <returns></returns>
        public static int UpdateModel(string sql, object o)
        {
            var s = sql.Split('@');
            return Update(sql, s.Length ==  ? null : GetSqlParameters(o, s));
        }
        /// <summary>
        ///  查询数据
        /// </summary>
        /// <typeparam name="T">映射的实体类</typeparam>
        /// <param name="sql">执行的SQL语句</param>
        /// <param name="o">传递的实体类对象 要求该类中字段必须和 sql参数名称一致 不区分大小写 </param>
        /// <returns></returns>
        public static List<T> SeleteModel<T>(string sql, object o) where T : class, new()
        {
            var s = sql.Split('@');
            return Select<T>(sql, s.Length ==  ? null : GetSqlParameters(o, s));
        }
        /// <summary>
        /// 动态创建SqlParameter 对象
        /// </summary>
        /// <param name="o">传递的实体类对象 要求该类中字段必须和 sql参数名称一致 不区分大小写 </param>
        /// <param name="s">切割后的SQL 语句</param>
        /// <returns></returns>
        private static SqlParameter[] GetSqlParameters(object o, string[] s)
        {
            s = s.Select(c => c.Split(' ')[].Trim()).ToArray(); 
            Type t = o.GetType();
            if (t == typeof(object))
                throw new Exception("UpdateModel  传递的类型是OBJECT 类型");
            // 反射 读取字段 验证是否是 SQL 中的参数
            var tlist =
                t.GetFields(BindingFlags.Public | BindingFlags.Instance)
                    .Where(c => c.GetValue(o) != null & s.FirstOrDefault(a => a.ToLower() == c.Name.ToLower()) != null)
                    .ToList();
            // 判断得到的数据 是否和 需要的数据 数量一致
            if (tlist.Count() != s.Count() - )
                throw new Exception("传递的实体中有值参数 和 sql 中需要的 数量不相等");
            SqlParameter[] sp = new SqlParameter[tlist.Count()];
            for (int i = ; i < s.Length - ; i++)
            {
                sp[i] = new SqlParameter(s[i + ].Trim(), tlist.FirstOrDefault(c => c.Name.ToLower() == s[i + ].ToLower()).GetValue(o));
            }
            return sp;
        }
        private static List<T> SeleteModel<T>(SqlDataReader data) where T : class, new()
        {
            // 获取列 个数
            int iFieldCount = data.FieldCount;
            List<T> list = new List<T>();
            while (data.Read())
            {
                T tType = new T();
                for (int i = ; i < iFieldCount; i++)
                {
                    // 反射注入字段值
                    string dataName = data.GetName(i);
                    FieldInfo fie = tType.GetType().GetField(dataName);
                    if (fie == null)
                        continue;
                    fie.SetValue(tType, data[dataName]);
                }
                list.Add(tType);
            }
            return list;
        }
        private static List<T> Select<T>(string sql, SqlParameter[] sp) where T : class, new()
        {
            using (SqlConnection conn = new SqlConnection(ConnectionString))
            {
                using (SqlCommand com = new SqlCommand(sql, conn))
                {
                    conn.Open();
                    if (sp != null)
                        com.Parameters.AddRange(sp);
                    return SeleteModel<T>(com.ExecuteReader());
                }
            }
        }
        private static int Update(string sql, SqlParameter[] sp)
        {
            using (SqlConnection conn = new SqlConnection(ConnectionString))
            {
                using (SqlCommand com = new SqlCommand(sql, conn))
                {
                    conn.Open();
                    if (sp != null)
                        com.Parameters.AddRange(sp);
                    return com.ExecuteNonQuery();
                }
            }
        }
调用示例:
public class TestCalss
{
public static void Main()
{
string sql = @"SELECT TOP 1000 [ID]
,[ExpressID]
,[OrderID]
,[MailCode]
,[SendXML]
,[SendFlag]
,[SendCount]
FROM [SendStateTest] where id=@id and SendXML=@SendXML "; string sql2 = @"update [DangDang_SendStateTest] set SendXML='0000' where id=@id "; int i = AdoConnection.UpdateModel(sql2, new Na() { ID = 1 }); List<Na> a = AdoConnection.SeleteModel<Na>(sql, new Na() { ID = 1, SendXML = "0000" });
Console.WriteLine(a);
} public class Na
{
public int ID;
public string ExpressID;
public string OrderID;
public string MailCode;
public string SendXML;
public int SendFlag;
public int SendCount; }
}
只是提供一种自己做一个简单的 三分之一 “ORM” 的 方式 (没有连接池 还得写Sql )
说实话,自己弄的在好,也不如 网上大家都在用的 “ORM” 框架
可以在这个简单的 “ORM” 上经行加工 拓展, 比如 支持存储过程 不限定数据库 SQL 语句 分类 等等
有兴趣的朋友可以自己做做 ,我就不弄了。
如果你使用过多种ORM 你就会发现 越是功能全 越是强大的ORM 效率就越低 因为不管是哪个ORM 最后还是对JDBC/ADO.NET 的加工封装 。
EF 效率是低 但是 他的 是 我弄过的一下ORM框架中 是功能最全 除去效率外 其他都很强大。
.Net 自己写个简单的 半 ORM (练手)的更多相关文章
- 简单的node爬虫练手,循环中的异步转同步
		
简单的node爬虫练手,循环中的异步转同步 转载:https://blog.csdn.net/qq_24504525/article/details/77856989 看到网上一些基于node做的爬虫 ...
 - (原创)如何使用boost.asio写一个简单的通信程序(二)
		
先说下上一篇文章中提到的保持io_service::run不退出的简单办法.因为只要异步事件队列中有事件,io_service::run就会一直阻塞不退出,所以只要保证异步事件队列中一直有事件就行了, ...
 - django写一个简单的登陆注册
		
要写这个,前提还是需要知道三个知识: 一个是urls.py,它是写我们的路由关系的,之前我写了通过wsgiref写一个简单的服务端,也用到了路由,就是 请求过来的url和视图函数的对应关系. 二是就是 ...
 - 用Python写一个简单的Web框架
		
一.概述 二.从demo_app开始 三.WSGI中的application 四.区分URL 五.重构 1.正则匹配URL 2.DRY 3.抽象出框架 六.参考 一.概述 在Python中,WSGI( ...
 - 如何写一个简单的http服务器
		
最近几天用C++写了一个简单的HTTP服务器,作为学习网络编程和Linux环境编程的练手项目,这篇文章记录我在写一个HTTP服务器过程中遇到的问题和学习到的知识. 服务器的源代码放在Github. H ...
 - 如何写一个简单的shell
		
如何写一个简单的shell 看完<UNIX环境高级编程>后我就一直想写一个简单的shell来作为练习,因为有事断断续续的写了好几个月,如今写了差不多来总结一下. 源代码放在了Github: ...
 - 用C#Winform写个简单的批量清空文件内容和删除文件的小工具
		
用C#Winform写个简单的批量清空文件内容和删除文件的小工具 本文介绍这个简单得不能再简单的小项目.做这个项目,有以下目的. 1 当然是做个能用的工具 2 学习使用Github 关于用VS2013 ...
 - 分享:计算机图形学期末作业!!利用WebGL的第三方库three.js写一个简单的网页版“我的世界小游戏”
		
这几天一直在忙着期末考试,所以一直没有更新我的博客,今天刚把我的期末作业完成了,心情澎湃,所以晚上不管怎么样,我也要写一篇博客纪念一下我上课都没有听,还是通过强大的度娘完成了我的作业的经历.(当然作业 ...
 - linux设备驱动归纳总结(十一):写个简单的看门狗驱动【转】
		
本文转载自:http://blog.chinaunix.net/uid-25014876-id-112879.html linux设备驱动归纳总结(十一):写个简单的看门狗驱动 xxxxxxxxxxx ...
 
随机推荐
- GroupId和ArtifactId
			
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc --><dependency> ...
 - 【caffe-windows】 caffe-master 之 cifar10 超详细
			
本教程尽量详细,大多步骤都有图,如果运行出错,请先对照自己的文件是否和图上的一样,包括标点啊,空格啊,斜杠,反斜杠啊之类的小细节. 本例程是在 win10 64位 caffe-master ...
 - 有关OpenCV1.0中GUI命令的几个函数学习总结
			
1.修改窗口背景色或者光标形状 在OpenCV1.0版本利用函数int cvNamedWindow( const char* name, int flags )初始化创建一个窗口后,窗口的背景色是灰色 ...
 - Unity3D 新人学习的一点感想
			
想到那里写到那里吧 1.Unity3D的优点大家都知道:组件化.c#语言.可见即所得. 当初刚开始学习的是cocos2dx,c++的货,觉得还是写的不错的,也是国人开发的,真的代码很容易懂,直接看引擎 ...
 - Socket WSAAsyncSelect模型
			
::WSAAsyncSelect(sListen, hWnd, WM_SOCKET, FD_ACCEPT|FD_CLOSE); 自定义 WM_SOCKET消息 #include "../co ...
 - markdown语法学习效果预览
			
注: 结合markdown官方文档 其中大部分例子和说明文字都摘自官方文档 官方链接:Markdown: Basics (快速入门). 一 段落.标题.区块代码 Markdown 支持两种标题的语法, ...
 - hibernate 问题
			
如果hibernate中反转的表中没有主键的话,会生产三个文件. table.java tableADO.java tableId.java 并且在执行findByProperty时,会提示:coul ...
 - JS常用的设计模式(13)——组合模式
			
组合模式又叫部分-整体模式,它将所有对象组合成树形结构.使得用户只需要操作最上层的接口,就可以对所有成员做相同的操作. 一个再好不过的例子就是jquery对象,大家都知道1个jquery对象其实是一组 ...
 - 信息图形(Infographic)
			
信息图形(Infographic),又称为信息图,是指数据.信息或知识的可视化表现形式.信息图形主要应用于必须要有一个清楚准确的解释或表达甚为复杂且大量的信息,例如在各式各样的文件档案上.各个地图及标 ...
 - Splash Screen开场屏在Android中的实现
			
很多网友可能发现近期Tencent推出的手机QQ Android版包含了一个开场屏Splash Screen载入效果,通常游戏或大型软件打开时可能需要一个释放解析资源的过程,需要一个前台的动画播放和后 ...