DapperPoco -- 基于Dapper的、轻量级的、高性能的、简单的、灵活的ORM框架
来源:互联网 发布:ntp服务器修改端口 编辑:程序博客网 时间:2024/05/15 15:45
为什么要重复造轮子
因为现有的轮子都在某些方面不太令我满意,下面我来一一点评一下,欢迎拍砖。
Entity Framework
我喜欢傻瓜化使用方式的框架,同时又不失灵活性。
EF虽然使用起来足够简单,但却不够灵活。例如,在EF Core中你无法用原生SQL写一个多表连接查询(返回的结果是多表连接的结果)
单表简单条件查询还好,多表查询时生成的SQL性能实在不敢恭维,我更喜欢自己写SQL,可控性更高,心里有底
EF的设计不利于项目的分层;我理想的设计是隔离、低耦合,和数据库打交道的事就交给Db层好了,所有数据库的特性都隔离在Db层内部,对外按业务提供傻瓜化的接口。
而使用EF你没法做到真正的隔离
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", 1);//更新除主键外的所有列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 = 1, 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", 1);//删除实体记录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 [] { 1, 2, 3 });//查询单条记录masterDb.FirstOrDefault<Article>("select * from T_Article where article_id = @p0", 1);//查询单列var count = masterDb.ExecuteScalar<long>("select count(*) from T_Article");//查询分页的结果(第1页,每页20条)Paged<Article> paged = masterDb.Paged<Article>(1, 20, "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();}
0 0
- DapperPoco -- 基于Dapper的、轻量级的、高性能的、简单的、灵活的ORM框架
- DapperPoco -- 基于Dapper的、轻量级的、高性能的、简单的、灵活的ORM框架
- 基于轻量级ORM框架Dapper的扩展说明
- 基于轻量级ORM框架Dapper的扩展说明
- (原创,开源)高灵活度,高适用性,高性能,轻量级的 ORM 实现
- MyBatis 灵活的ORM框架
- ECommon.Dapper 轻量级的dapper扩展
- Dapper:.NET框架下的轻型的ORM类
- 轻量级ORM框架——第二篇:Dapper中的一些复杂操作和inner join应该注意的坑
- 轻量级ORM框架——第二篇:Dapper中的一些复杂操作和inner join应该注意的坑
- 轻量级ORM框架——第二篇:Dapper中的一些复杂操作和inner join应该注意的坑
- _net平台性能很不错的轻型ORM类Dapper
- .net平台性能很不错的轻型ORM类Dapper
- c# .net orm 框架 dapper.net 的应用
- c# .net orm 框架 dapper.net 的应用
- android 超轻量级的ORM框架
- 一个超轻量级的 ORM 框架
- Dapper-轻量级ORM框架
- 用Visual Studio Code Debug世界上最好的语言
- JavaScript数据结构——队列的实现
- 前端总结·基础篇·JS(三)arguments、callee、call、apply、bind及函数封装和构造函数
- erlang:send_after和erlang:start_timer的使用解释
- 初用Linux, 安装Ubuntu16.04+NVIDIA387+CUDA8.0+cudnn5.1+TensorFlow1.0.1
- DapperPoco -- 基于Dapper的、轻量级的、高性能的、简单的、灵活的ORM框架
- wxpython分割窗研究(解决sashPosition=0无效的BUG)
- WPF: 在 MVVM 设计中实现对 ListViewItem 双击事件的响应
- 一段Java有意思的代码
- Spring Boot启动过程(六):内嵌Tomcat中StandardHost、StandardContext和StandardWrapper的启动
- Leetcode 500. Keyboard Row
- Leetcode 461. Hamming Distance
- Leetcode 476. Number Complement
- 读headFirst设计模式