SuperHelper——灵活通用的、开源的.Net ORM微型框架
SuperHelper是博主利用业余时间编写的一个ORM微型框架,除了可以提高开发效率,与其它ORM框架相比,博主更加喜欢SuperHelper的使用简单、适用范围广的特点。
简介
SuperHelper是一个基于.Net平台的非侵入式的的微型ORM框架,可帮助开发者快速简便的访问数据库并对其操作,且部署起来十分简单;只依赖于相应的数据库引擎,开发者可以根据实际项目需要增加引用不同版本的SuperHelper组件,且不会产生冲突。(目前SuperHelper有SQlServer版和SQLite版)
以下是SuperHelper的概要特点:
1、部署十分简单。开发者只需在项目配置文件中为SuperHelper指定一个可用的连接字符串即可完成部署。
2、适用范围广。SuperHelper可以在经典三层架构项目、一般处理程序+模板引擎项目、WebForm、MVC架构项目等等都可以使用,项目中如果需要切换使用不同数据库引擎则只需切换相应版本的SuperHelper组件即可。还有,SuperHelper可以与其它ORM框架如微软的EF、NHibernate等混可使用且不会产生任何冲突。同时因为SuperHelper是一个非侵入式的ORM框架,项目不会对SuperHelper有过多的依赖,开发者依然可以把代码很方便的迁移到其他地方。
3、使用灵活。写好sql语句之后,开发者只需要再写一行代码即可完成访问数据库并返回相应数据实体的操作(SuperHelper还支持对实体类的复杂类型属性或字段赋值)。ps:与一些微型ORM一样,SuperHelper是不支持LinQ的,不过针对SQlServer,SuperHelper支持存储过程的调用。
使用方法
下面的使用方法介绍中,如无特别说明,皆以SuperHelper的SQlServer版本为例。
1、部署:
首先在项目的配置文件中为SuperHelper指定一条可用的数据库连接字符串,将其Name属性设置为“SuperHelper_SQLServer”,如下代码所示。(这里是根据不同版本的SuperHelper组件的命名空间决定,如果使用SuperHelper的SQLite版,则Name属性应为“SuperHelper_SQLite”)。
<connectionStrings>
<add name="SuperHelper_SQLServer" connectionString="Data Source=127.0.0.1;Initial Catalog=News;Integrated Security=True"/>
</connectionStrings>
至此,SuperHelper的部署工作就已经完成了,接下来,只需要在解决方案的某个项目中添加引用SuperHelper_SQLServer组件即可。
2、SuperHelper的方法调用
对于SuperHelper而言,所有数据库访问操作分为两种:查询、非查询(增,删、改)。
为了演示方便,博主准备一个测试用的新闻数据库News和相应的实体类,如果大家习惯使用自己数据库来测试,则可以跳过准备过程,直接看代码。
下面是News数据库的sql语句脚本,用于生成该数据库的架构和少量的测试数据。
CREATE DATABASE [News]
CONTAINMENT = NONE
ON PRIMARY
( NAME = N'News', FILENAME = N'此处要改为本地路径\News.mdf' , SIZE = 5120KB , MAXSIZE = 10240KB , FILEGROWTH = 1024KB )
LOG ON
( NAME = N'News_log', FILENAME = N'此处要改为本地路径\News.ldf' , SIZE = 2048KB , MAXSIZE = 10240KB , FILEGROWTH = 3072KB ) USE [News]
CREATE TABLE [dbo].[NewsInfo](
[NewsID] [int] IDENTITY(1,1) NOT NULL,
[NewsTitle] [nvarchar](50) NULL,
[SubTime] [datetime] NULL,
[TypeID] [int] NULL,
[NewsContent] [nvarchar](max) NULL
) CREATE TABLE [dbo].[TypeInfo](
[TypeID] [int] IDENTITY(1,1) NOT NULL,
[TypeTitle] [nvarchar](50) NULL
) USE [News]
GO
SET IDENTITY_INSERT [dbo].[NewsInfo] ON GO
INSERT [dbo].[NewsInfo] ([NewsID], [NewsTitle], [SubTime], [TypeID], [NewsContent]) VALUES (1, N'测试', CAST(N'2014-10-30 00:00:00.000' AS DateTime), 1, N'测试文档')
GO
INSERT [dbo].[NewsInfo] ([NewsID], [NewsTitle], [SubTime], [TypeID], [NewsContent]) VALUES (2, N'测试123', CAST(N'2013-05-06 00:00:00.000' AS DateTime), 2, N'这是一张大图')
GO
INSERT [dbo].[NewsInfo] ([NewsID], [NewsTitle], [SubTime], [TypeID], [NewsContent]) VALUES (3, N'test456', CAST(N'2013-06-07 00:00:00.000' AS DateTime), 3, N'')
GO
INSERT [dbo].[NewsInfo] ([NewsID], [NewsTitle], [SubTime], [TypeID], [NewsContent]) VALUES (5, N'你好', CAST(N'2014-05-06 00:00:00.000' AS DateTime), 2, N'sdfvszgvsz')
GO
INSERT [dbo].[NewsInfo] ([NewsID], [NewsTitle], [SubTime], [TypeID], [NewsContent]) VALUES (6, N'APEC', CAST(N'2013-08-06 00:00:00.000' AS DateTime), 1, N'354asefsef65')
GO
INSERT [dbo].[NewsInfo] ([NewsID], [NewsTitle], [SubTime], [TypeID], [NewsContent]) VALUES (7, N'hahahah', CAST(N'2014-06-08 00:00:00.000' AS DateTime), 2, N'srgdfs')
GO
INSERT [dbo].[NewsInfo] ([NewsID], [NewsTitle], [SubTime], [TypeID], [NewsContent]) VALUES (8, N'weqwe', CAST(N'2012-01-05 00:00:00.000' AS DateTime), 4, N'5465dfsdfv')
GO
SET IDENTITY_INSERT [dbo].[NewsInfo] OFF
GO
SET IDENTITY_INSERT [dbo].[TypeInfo] ON GO
INSERT [dbo].[TypeInfo] ([TypeID], [TypeTitle]) VALUES (1, N'文字')
GO
INSERT [dbo].[TypeInfo] ([TypeID], [TypeTitle]) VALUES (2, N'图片')
GO
INSERT [dbo].[TypeInfo] ([TypeID], [TypeTitle]) VALUES (3, N'视频')
GO
INSERT [dbo].[TypeInfo] ([TypeID], [TypeTitle]) VALUES (4, N'音频')
GO
SET IDENTITY_INSERT [dbo].[TypeInfo] OFF
GO
News数据库生成脚本
数据库准备完成后,接下来是准备相应的数据库实体类。
public class NewsInfo
{
public int NewsID { get; set; }
public string NewsTitle { get; set; }
public DateTime SubTime { get; set; }
public int TypeID { get; set; }
public string NewsContent { get; set; }
} public class TypeInfo
{
public int TypeID { get; set; }
public string TypeTitle { get; set; }
}
实体类定义
至此,准备过程已完成,下面我们先来执行一条简单的sql语句。
using SuperHelper_SQLServer; namespace SuperHelper演示demo
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
} private void Form1_Load(object sender, EventArgs e)
{
string sql = "select * from NewsInfo"; List<NewsInfo> lst_news = SH_Query<NewsInfo>.GetListBySql(sql); dgv.DataSource = lst_news;
}
}
}
接下来,我们再来执行有参数的sql语句。(重复的代码,博主就不再贴出来,只贴关键的sql语句和执行代码)
//查询NewsID=1 和 TypeID=2 的新闻信息 #region 这是第一种写法
string sql = "select * from NewsInfo where NewsID = @NewsID and TypeID = @TypeID";
NewsInfo newinfo = new NewsInfo();
newinfo.NewsID = ;
newinfo.TypeID = 2; List<NewsInfo> lst_news = SH_Query<NewsInfo>.GetListBySql(sql, new List<object> { newinfo});
#endregion #region 这是第二种写法
string sql = "select * from NewsInfo where NewsID = @a and TypeID = @b";
int i = ;
int j = 2; List<NewsInfo> lst_news = SH_Query<NewsInfo>.GetListBySql(sql, new List<object> { i, j });
#endregion
看到这里,估计大家也能对SuperHelper的用法和原理有大概的认识了。
SuperHelper其实是根据匹配实体类的公共属性或者公共字段名称与执行sql语句的查询结果集中的列名称来产生映射关系;所以,如果实体类的属性或者字段名与sql语句查询的结果集的列名不一致(名称大小写也必须一致),那么就无法正确获取数据了。根据上面的代码举个例子:如果NewsInfo类中的NewsTitle属性改为newsinfo,而News数据库中NewsInfo表的NewsTitle列名保持不变,而因为上述sql语句执行后的结果集列名中只有“NewsTitle”而没有“newsinfo”,所以最终结果就是lst_news中的对象的NewsTitle属性都为空。
至于sql语句的参数匹配方式,大家可以参考下面的两种方法。
第一种写法:根据实体类对象的属性或者字段名与sql语句中的参数名进行匹配。同样的,根据上面的第一种写法代码举个例子:sql语句中的@NewsID必须与实体类对象newsinfo的属性名NewsID大小写一致,这样才能1赋值给参数@NewsID。
第二种写法:根据参数顺序匹配。同样的,根据上面的第二种写法代码举个例子:i 的值会赋给sql语句中第一个出现的参数,而不管参数@a改成什么名字。如果sql语句中同一个参数出现多次,则以该参数第一次出现的位置为准,例如sql语句是这样“..@b.....@a.....@b...@c....”,则参数集合new List<object>{i, j, k}中 i 会赋值给@b,j 赋值给@a,k 赋值给@c。
其实,上述两种匹配方法是可以混合使用的,由此可以得出第三种写法,代码如下:
//查询NewsID=1 和 TypeID = 2 的新闻信息 string sql = "select * from NewsInfo where NewsID = @NewsID and TypeID = @a"; NewsInfo newinfo = new NewsInfo();
newinfo.NewsID = ;
int i = ; List<NewsInfo> lst_news = SH_Query<NewsInfo>.GetListBySql(sql, new List<object> { newinfo, i});
SuperHelper会优先根据实体类的属性与字段与sql语句中的参数进行匹配,而剩下的无法与实体类匹配成功的参数则按照顺序来进行二次匹配(ps:已经与实体类匹配好的sql参数不会参加二次匹配的排序)
上面简介中还提到,SuperHelper还支持对实体类的复杂类型属性或字段赋值,为了演示这个功能,我们需要对上述NewsInfo类中添加一个class类型的属性,完整NewsInfo定义如下:
public class NewsInfo
{
public int NewsID { get; set; }
public string NewsTitle { get; set; }
public DateTime SubTime { get; set; }
public int TypeID { get; set; }
public string NewsContent { get; set; } public TypeInfo Ti { get; set; } //TypeInfo类是上面准备过程中定义好的类
}
对于这个TypeInfo类型的属性Ti,即使数据库中NewsInfo表中也含有名称为Ti的列,使用上述提到的sql语句是没办法完成数据获取的,需要对其sql语句进行稍加修改,代码如下:
//对实体类中的复杂属性或字段进行数据匹配 string sql = "select NewsID,NewsTitle,NewsContent,TypeTitle as [Ti.TypeTitle] from NewsInfo left join TypeInfo on NewsInfo.TypeID=TypeInfo.TypeID"; List<NewsInfo> lst_news = SH_Query<NewsInfo>.GetListBySql(sql);
此时,大家可以断点调试,查看lst_news中NewsInfo对象中Ti属性中的TypeTitle属性赋值已经成功了。其实整个修改过程也很简单,就是将查询结果集中的列名“TypeTitle”改成“Ti.TypeTitle”即可。这就跟你在VS中写代码一样,想要获取某个类的属性时,只需用“.”就可以获取到了,意思是一样的。当然,如果Ti中也含有class类型的属性或字段时,可以继续以“.”方式对其进行赋值,如:“Ti.class类型的属性名或字段名.class类型的属性名或字段名.class类型的属性名或字段名”,以此类推。
至此,SuperHelper中主要的查询方法的使用要点已经基本介绍完毕了,至于非查询的方法使用与查询方法基本一致,只不过非查询固定返回值是受影响行数而已。当然,SuperHelper中还有支持临时切换访问不同数据库,SQLServer版还支持存储过程等等。但博文篇幅有限,在此就不多详述了,有时间的话博主会再详细写其它用法。
SuperHelper源码地址:https://github.com/honker-bin/SuperHelper
最后再说几句话,博主不是什么技术大牛,但是大牛之所以是大牛,除了技术牛X之外,善于分享是他们共同的特点。其实很多程序员朋友在长期的开发过程积累了不少有用的技术与经验,不是不想分享,而是懒得分享,但是要知道,技术除了不断学习,分享和交流也是迅速提高自身的捷径之一(这一点博主深有体会)。最后调侃一下,这年头连微软都开源了,你还懒得分享自己的技术经验吗?:)
作者:冯礼斌
文章出处:http://www.cnblogs.com/fenglibin/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
SuperHelper——灵活通用的、开源的.Net ORM微型框架的更多相关文章
- 开源的.Net ORM微型框架SuperHelper
SuperHelper——灵活通用的.开源的.Net ORM微型框架 SuperHelper是博主利用业余时间编写的一个ORM微型框架,除了可以提高开发效率,与其它ORM框架相比,博主更加喜欢Supe ...
- ent facebook 开源的golang orm 框架
ent 是facebook 开源的golang orm 框架,简单强大,具有提下特性 schema 即代码 方便的图遍历 静态类型以及显示api 多种存储引擎支持(当前是mysql,sqlite,以及 ...
- ORM数据库框架 greenDAO SQLite MD
Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...
- ORM数据库框架 SQLite 常用数据库框架比较 MD
Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...
- C#实现多级子目录Zip压缩解压实例 NET4.6下的UTC时间转换 [译]ASP.NET Core Web API 中使用Oracle数据库和Dapper看这篇就够了 asp.Net Core免费开源分布式异常日志收集框架Exceptionless安装配置以及简单使用图文教程 asp.net core异步进行新增操作并且需要判断某些字段是否重复的三种解决方案 .NET Core开发日志
C#实现多级子目录Zip压缩解压实例 参考 https://blog.csdn.net/lki_suidongdong/article/details/20942977 重点: 实现多级子目录的压缩, ...
- android高效ORM数据库框架greenDao使用
因为项目中多处用到了数据库,需要对数据库频繁的读写操作,虽然android 自带的SQLiteOpenHelper的.这种方式比较方便易懂,但是在使用过程中需要写很多的sql语句,而且需要及时的关闭和 ...
- ORM数据库框架 LitePal SQLite MD
Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...
- 几款开源的hybird移动app框架分析
几款开源的Hybrid移动app框架分析 Ionic Onsen UI 与 ionic 相比 jQuery Mobile Mobile Angular UI 结论 很多移动开发者喜欢使用原生代码开发, ...
- asp.Net Core免费开源分布式异常日志收集框架Exceptionless安装配置以及简单使用图文教程
最近在学习张善友老师的NanoFabric 框架的时了解到Exceptionless : https://exceptionless.com/ !因此学习了一下这个开源框架!下面对Exceptionl ...
随机推荐
- 第三章 八位数字开关板&模拟输入板&火焰传感器
这节我将带大家了解亮宁机器人基础外接硬件. 八位数字板开关 接线方法:W1~W8接23~37号数字端口,Enter接39号数字端口,vcc和gnd分别接正负. #include <LNDZ.h& ...
- 快速提取邮箱地址(利用word或网站)
在word中,CTRL+F,输入:[A-z,0-9]{1,}\@[A-z,0-9,\.]{1,} 点击“高级”,勾选“使用通配符”,点击“查找全部”: 复制.粘贴. 还可通过以下页面在线提取. htt ...
- Unity3D转UE4指南
坐标: Unity3D X - left, right Y - up, down Z - forwards, backwards Unreal Engine4 X - forwards, backwa ...
- Last_IO_Errno: 1032
(一):更新找不到记录 1032 Last_SQL_Errno: 1032 Last_SQL_Error: Could not execute Update_rows ...
- selenium添加cookie切换到不同环境
背景:网站中需要切环境到预发布,在用谷歌浏览器可以使用工具,但是在selenium启动时,是不会带任何插件,向开发了解下,切换环境本质是添加cookie值,那么这个就简单了 1.使用selenium中 ...
- Edmonds-Karp算法,最大流POJ(1459)
题目链接:http://poj.org/problem?id=1459 解题报告: 电力调度站不涉及流的产生和消耗,不用考虑,Edmonds-Karp算法,就是利用剩余网络和增广路来解决,网络中的最大 ...
- vue中css动画原理
显示原理: <transition name='fade'> <div v-if='show'>hello world</div> </transition& ...
- spring教程(一):简单实现(转)
转:https://www.cnblogs.com/Lemon-i/p/8398263.html 一.概念介绍 1. 一站式框架:管理项目中的对象.spring框架性质是容器(对象容器) 2. 核心 ...
- python—命名空间、作用域查找顺序、闭包
名称空间 name space,如下图: x = 1, 1存放在内存中,1 会有一个内存地址,x 则 存放在 name space 里,并同时记录了 1的内存地址, 即 名称空间是存放了变量x与1绑定 ...
- mask r-cnn
mask R-cnn, kaiming he的新作.可以同时完成object detection和segmentation,还可以做pose estimation,简直就是功能多多啊.在coco上测试 ...