DapperPoco -- 基于Dapper的、轻量级的、高性能的、简单的、灵活的ORM框架
为什么要重复造轮子
因为现有的轮子都在某些方面不太令我满意,下面我来一一点评一下,欢迎拍砖。
Entity Framework
我喜欢傻瓜化使用方式的框架,同时又不失灵活性。
EF虽然使用起来足够简单,但却不够灵活。例如,在EF Core中你无法用原生SQL写一个多表连接查询(返回的结果是多表连接的结果)
单表简单条件查询还好,多表查询时生成的SQL性能实在不敢恭维,我更喜欢自己写SQL,可控性更高,心里有底
EF的设计不利于项目的分层;我理想的设计是隔离、低耦合,和数据库打交道的事就交给Db层好了,所有数据库的特性都隔离在Db层内部,对外按业务提供傻瓜化的接口。
而使用EF你没法做到真正的隔离,因为即使能把SaveChanges封装在Db层,导航属性也会导致再次查询数据库。
Dapper
我喜欢它的轻量级,高性能。但它"只支持"原生SQL读写数据库,使用起来还是不太方便。
很多常用的情景其实可以封装一下不用写SQL的,像EF一样,直接Add一个Entity
虽然现在Dapper已经有了这样一个封装,但目前来看实在过于粗糙
PetaPoco
它可以像EF一样直接Add一个Entity,也可以像Dapper一样自己写原生SQL,按理说这已经很完美了。
但是,它不支持批量插入、更新啊
DapperPoco
在实在找不到满意框架的情况下,于是DapperPoco就诞生了,它是基于Dapper高度封装的,有Dapper的一切优点,同时也弥补了它的不足,它有如下特点:
- 高性能(与Dapper一致),以热启动后计算(第一次启动有缓存过程)
- 像EF一样使用简单,也可像Dapper一样灵活使用原生SQL
- 支持使用Fluent API定义实体映射
- 内部模块化灵活、可扩展
现已将其开源并放到了github上,地址为:https://github.com/md-frank/DapperPoco
如何使用
首先定义一个Poco类
//表示文章表里的一条记录
public class Article
{
public long Id { get; set; }
public string Title { get; set; }
public string Content { get; set; }
}
创建DbContext
class MasterDbContext : DbContext
{
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseConnectionString("连接字符串");
//使用SQL Server数据库
optionsBuilder.UseSqlAdapter(new SqlServerAdapter(SqlClientFactory.Instance));
} //如果不使用Poco可以不重写此方法
protected override void OnEntitiesBuilding(EntitiesBuilder entityBuilder)
{
//属性名与表列名(列名)不一样,可在此映射别名
entityBuilder.Entity<Article>()
.TableName("T_Article")
.ColumnName(p => p.Id, "article_id");
}
}
插入数据
var masterDb = new MasterDbContext(); //插入一个Poco对象
var a = new Article
{
Title = "hello",
Content = "hello word"
};
masterDb.Insert(a); //插入了2条记录
masterDb.Insert(new Article[] { a, a }); //也可以显式指定表名
masterDb.Insert(a, "T_Article"); //原生SQL插入
this.Execute("insert T_Article(Title, Content) values (@Title, @Content)", a); //插入了2条记录
this.Execute("insert T_Article(Title, Content) values (@Title, @Content)", a, a); //插入了2条记录
this.Execute("insert T_Article(Title, Content) values (@Title, @Content)", new Article[] { a, a }); //也可以直接写参数值
this.Execute("insert T_Article(Title, Content) values (@p0, @p1)", "hello", "hello word");
更新数据
var masterDb = new MasterDbContext(); //先查出来准备更新
var article = masterDb.FirstOrDefault<Article>("select * from T_Article where article_id = @p0", ); //更新除主键外的所有列
article.Title = "hello 2";
article.Content = "content 1";
masterDb.Update(article); //仅更新指定列,指定表列名
article.Title = "hello 2";
masterDb.Update(article, new [] { "Title" }); //仅更新指定列,指定实体属性名
article.Title = "hello 3";
article.Content = "content 1";
masterDb.Update(article, null, null, p=> p.Title, p=> p.Content);
保存数据
var masterDb = new MasterDbContext(); var article = new Article
{
Id = ,
Title = "hello",
Content = "hello word"
}; //如果记录存在则更新,不存在则插入
masterDb.Save(article); //保存并指定列名
masterDb.Save(article, new [] { "Title" });
删除数据
var masterDb = new MasterDbContext();
var article = masterDb.FirstOrDefault<Article>("select * from T_Article where article_id = @p0", );
//删除实体记录
masterDb.Delete(article);
//删除实体记录,显式指定主键名
masterDb.Delete(article, "article_id");
查询数据(立即执行)
var masterDb = new MasterDbContext(); //查询T_Article表所有记录
var articles = masterDb.FetchAll<Article>(); //指定条件查询,直接写参数值
var articles = masterDb.Fetch<Article>("select * from T_Article where Title=@p0 and Content=@p1", "hello", "hello word"); //指定条件查询,支持列表(实现了IEnumerable接口的)
var articles = masterDb.Fetch<Article>("select * from T_Article where article_id in @p0", new [] { , , }); //查询单条记录
masterDb.FirstOrDefault<Article>("select * from T_Article where article_id = @p0", ); //查询单列
var count = masterDb.ExecuteScalar<long>("select count(*) from T_Article"); //查询分页的结果(第1页,每页20条)
Paged<Article> paged = masterDb.Paged<Article>(, , "select * from T_Article where Title=@p0", "hello"); //Paged的定义如下
public class Paged<T> where T : new()
{
//当前页码
public int CurrentPage { get; set; } //总页数
public int TotalPages { get; set; } ///总记录数
public long TotalItems { get; set; } //每页记录数
public int ItemsPerPage { get; set; } //当前页记录列表
public List<T> Items { get; set; }
}
查询数据(延迟执行)
延迟查询使用Query,与Fetch不同的是Query返回的结果只有在使用时才会真正查询数据库
var masterDb = new MasterDbContext(); //延迟查询
var articles = masterDb.Query<Article>("select * from T_Article where Title=@p0", "hello");
动态查询条件
var title = "此变量来自用户输入"; var sb = new SqlBuilder();
sb.Append("select * from T_Article");
if(!string.IsNullOrEmpty(title))
sb.Append("where Title=@p0", title); var sql = sb.Build();
var articles = masterDb.Fetch<Article>(sql.Statement, sql.Parameters);
事务支持
using (var trans = this.GetTransaction())
{
//这里修改数据库 //提交事务
trans.Complete();
}
DapperPoco -- 基于Dapper的、轻量级的、高性能的、简单的、灵活的ORM框架的更多相关文章
- 分享自己写的基于Dapper的轻量级ORM框架~
1.说明 本项目是一个使用.NET Standard 2.0开发的,基于 Dapper 的轻量级 ORM 框架,包含基本的CRUD以及根据表达式进行一些操作的方法,目前只针对单表,不包含多表连接操作. ...
- ORM框架之------Dapper,Net下无敌的ORM
一,介绍:Dapper是一款轻量级ORM工具.如果你在小的项目中,使用Entity Framework.NHibernate 来处理大数据访问及关系映射,未免有点杀鸡用牛刀.你又觉得ORM省时省力,这 ...
- 基于轻量级ORM框架Dapper的扩展说明
这里简单的介绍一下本人基于Dapper作的一些简单的扩展,供大家参考. 为何要使用这款框架,相信大家看到下面排名就清楚了 其实在各大网站上,我们大概都会看到这样的一个对比效果图,在超过500次poco ...
- 【原创】基于.NET的轻量级高性能 ORM - TZM.XFramework
[前言] 接上一篇<[原创]打造基于Dapper的数据访问层>,Dapper在应付多表自由关联.分组查询.匿名查询等应用场景时不免显得吃力,经常要手写SQL语句(或者用工具生成SQL配置文 ...
- PetaPoco - 轻量级高性能的ORM框架(支持.NET Core)
我们都知道ORM全称叫做Object Relationship Mapper,也就是可以用object来map我们的db. 而且市面上的orm框架有很多,有重量级的Entity Framework,有 ...
- [开源] gnet: 一个轻量级且高性能的 Golang 网络库
Github 主页 https://github.com/panjf2000/gnet 欢迎大家围观~~,目前还在持续更新,感兴趣的话可以 star 一下暗中观察哦. 简介 gnet 是一个基于 Ev ...
- .net core 基于Dapper 的分库分表开源框架(core-data)
一.前言 感觉很久没写文章了,最近也比较忙,写的相对比较少,抽空分享基于Dapper 的分库分表开源框架core-data的强大功能,更好的提高开发过程中的效率: 在数据库的数据日积月累的积累下,业务 ...
- 基于netty轻量的高性能分布式RPC服务框架forest<下篇>
基于netty轻量的高性能分布式RPC服务框架forest<上篇> 文章已经简单介绍了forest的快速入门,本文旨在介绍forest用户指南. 基本介绍 Forest是一套基于java开 ...
- 基于netty轻量的高性能分布式RPC服务框架forest<上篇>
工作几年,用过不不少RPC框架,也算是读过一些RPC源码.之前也撸过几次RPC框架,但是不断的被自己否定,最近终于又撸了一个,希望能够不断迭代出自己喜欢的样子. 顺便也记录一下撸RPC的过程,一来作为 ...
随机推荐
- 初识Dapper
16年年底开发一个项目,拍卖的项目,对于我这个不入流的程序员来说,雪微是个挑战.程序猿这个行业就是学到老用到老吧.个人比较喜欢sql原生的写法,对EF 还是不怎么感冒,EF 虽然强大,但是用起来还不怎 ...
- 转载:深入探讨 Java 类加载器
转载地址 : http://www.ibm.com/developerworks/cn/java/j-lo-classloader/ 深入探讨 Java 类加载器 类加载器(class loader) ...
- PowerPoint实用知识
纯手打,可能有错别字,使用的版本是office2013 转载请注明出处 http://www.cnblogs.com/hnnydxgjj/p/6347256.html ,谢谢 母版的使用 制作PPT的 ...
- Spark:使用Spark Shell的两个示例
Spark:使用Spark Shell的两个示例 Python 行数统计 ** 注意: **使用的是Hadoop的HDFS作为持久层,需要先配置Hadoop 命令行代码 # pyspark >& ...
- loadrunner解决浏览器死机问题
初次接触loadrunner时,遇到很多问题.浏览器崩溃以及录不到脚本就折磨了一周时间.最后终于解决 一.浏览器崩溃问题 1.退出安全卫士和防火墙 2.去掉IE第三方扩展.工具-Internet选项- ...
- 重写titleView
在一些特定的情况下不能使用原有的titleView需要重写titleView代码如下 #import "TitleView.h" @implementation TitleView ...
- Android搜索框以及内容提供器
先看结果: 相关的官方文档在这里:Creating a Search Interface Android官方提供了两种方式: 弹出一个Dialog,覆盖当前的Activity界面 在AppBar中扩展 ...
- matlab 逻辑数组及其应用
这几天学习了matlab的逻辑数组功能,总的感觉就有两点: 第一,通过对原来的数组a进行逻辑判断后得到逻辑数组b 第二,逻辑数组进行某种运算符操作又回到原数组类型 第三,利用逻辑数组mask功能 测试 ...
- Apache 的安装
1.获取源码包 cd /usr/local/src/ ls wget http://mirrors.cnnic.cn/apache/httpd/httpd-2.4.25.tar.gz 2.解压.编译. ...
- 基于 GCDAsyncSocket,简单实现类似《你猜我画》的 socket 数据传输
一.前言 Socket Socket 是对 TCP/IP 协议的封装,其中IP协议对应为网络层,TCP 协议对应为传输层,而我们常用的HTTP协议,是位于应用层,在七层模型中HTTP协议是基于 TCP ...