轻量级ORM框架—Dapper

轻量级ORM框架—Dapper

Dapper是.NET下一个Micro的ORM,它和Entity Framework或NHibnate不同,属于轻量级的,并且是半自动的。也就是说实体类都要自己写。它没有复杂的配置文件,一个单文件就可以了。Dapper相当于Java里的Mybatis

个人觉得他非常好用,现在已经取代了原来的SqlHelper。优点:

  • 使用Dapper可以自动进行对象映射!
  • 轻量级,单文件。
    代码就一个SqlMapper.cs文件,编译后就40K的一个很小的Dll.
  • 支持多数据库。
    Dapper支持Mysql,SqlLite,Mssql2000,Mssql2005,Oracle等一系列的数据库,当然如果你知道原理也可以让它支持Mongo db,支持多数据库的本质是因为Dapper是对IDBConnection接口进行了方法扩展,
    比如你看到的SqlMapper.cs,一旦你这样做了,
    我们也知道,SqlConnection,MysqlConnection,OracleConnection都是继承于DBConnection,
    而DBConnection又是实现了IDBConnection的接口,对吧。。。
  • Dapper原理通过Emit反射IDataReader的序列队列,来快速的得到和产生对象。性能实在高高高。
  • Dapper语法简单,如果你喜欢写原始的sql,你一定喜欢Dapper。同时团队人员也很容易上手;
  • Dapper 速度快,速度接近ADO.NET访问数据库的效率;

基本的增删改查操作

Insert

Update

public int UpdateScanOmr(TB_SCAN_OMR1 model)
{
    string sqlstr = "UPDATE TB_SCAN_OMR1 " +
        "SET FINALOMR = :FINALOMR," +
        "    SCORE = :SCORE, " +
        "    SCOREDETAIL = :SCOREDETAIL" +
        " WHERE EXAMID = :EXAMID" +
        " AND PAPERID = :PAPERID";
    using (ExamConn)
    {
        return ExamConn.Execute(sqlstr, model);
    }
}

Delete

Query

  • 无参数查询,返回列表
public List<TB_EXAM> GetAllExam()
{
    var sqlstr = "SELECT * FROM TB_EXAM ORDER BY SDATE DESC";
    using (EmsConn)
    {
        return EmsConn.Query<TB_EXAM>(sqlstr).ToList();
    }
}
var entityList1 = new OmrRepository().GetAllExam();
foreach (var item in entityList1)
{
    Console.WriteLine(new Guid((byte[])item.EXAMGUID).ToString() + " " + item.EXAMNUM + " " + item.EXAMNAME);
}
  • 带参数查询
public List<TB_SCAN_PAGE> GetScanPageListByPaperId(string paperId)
{
    var sqlstr = "SELECT * FROM TB_SCAN_PAGE T WHERE T.PAPERID = :paperId";
    using (ExamConn)
    {
        return ExamConn.Query<TB_SCAN_PAGE>(sqlstr, new { paperId }).ToList();
    }
}
  • 单条信息
public TB_AREA GetAreaDeail(string examId,string areaId)
{
    var sqlstr = @"SELECT * FROM TB_AREA WHERE EXAMID = :examId AND AREAID = :areaId";
    using (ExamConn)
    {
        return ExamConn.Query<TB_AREA>(sqlstr, new { examId, areaId }).Single();
    }
}

事务操作

Dapper Extensions

Dapper-Extensions也是一个开源库,他在Dapper的基础上封装了基本的CRUD操作,使得一些简单的数据库操作可以不用自己写sql语句。使用起来更方面。
Dapper Extensions是github上的一个开源库是对StackOVerflow开发的Dapper ORM的一个扩展。它增加了基础的CRUD操作((Get, Insert, Update, Delete)),对更高级的查询场景,该类库还提供了一套谓词系统。它的目标是保持POCOs的纯净,不需要额外的attributes和类的继承。

Features

  • 零配置
  • 自动映射POCOs的CRUD操作
  • GetList, Count等方法可以用于更高级的场景。
  • GetPage for returning paged result sets.支持分页
  • 自动支持Guid和Integer类型的主键,(也可以手动指定其他键类型)
  • 通过使用ClassMapper可以使保证POCOs纯净。 (Attribute Free!)
  • 可以通过使用ClassMapper来自定义entity-table映射
  • 支持联合主键
  • POCO类名默认与数据表名相匹配,也可以自定义
  • 易于使用的 Predicate System适用于高级场合
  • 在生成SQL语句时正确转义表名和类名 (Ex: SELECT FirstName FROM Users WHERE Users.UserId = @ UserId_0)
  • 覆盖单元测试(覆盖了150+个单元测试)

Tdf.Dapper

more extensions for dapper

The full list of extension methods in Tdf.Dapper right now are:

Task<T> ExecuteScalarAsync(string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = default(int?), CommandType? commandType = default(CommandType?));
Task<IEnumerable<T>> QueryAsync(string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = default(int?), CommandType? commandType = default(CommandType?));
Task<IEnumerable<dynamic>> QueryAsyncDynamic(string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = default(int?), CommandType? commandType = default(CommandType?));
Task<int> ExecuteAsync(string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = default(int?), CommandType? commandType = default(CommandType?));
Task<T> GetAsync(int id, IDbTransaction transaction = null, int? commandTimeout = null);
Task<T> GetAsync(long id, IDbTransaction transaction = null, int? commandTimeout = null);
Task<T> GetAsync(System.Guid id, IDbTransaction transaction = null, int? commandTimeout = null);
Task<T> GetAsync(string id, IDbTransaction transaction = null, int? commandTimeout = null);
Task<int> InsertAsync(T model, IDbTransaction transaction = null, int? commandTimeout = null);
Task<bool> DeleteAsync(T model, IDbTransaction transaction = null, int? commandTimeout = null);
Task<T> UpdateAsync(T model, IDbTransaction transaction = null, int? commandTimeout = null);
Task<PageOutput> GetPageAsync(string sql, object p = null, string sqlTotal = "", object p2 = null);
Task<PageOutput> GetPageAsync(PageInput model, string tableName, string sqlWhere, dynamic pms1, dynamic pms2);

Features

For these extensions to work, the entity in question MUST have a key-property, a property named "id" or decorated with a [Key] attribute.

[Table("TB_COURSE")]
public class Course
{
    [Key]
    public int COURSEID { get; set; }
    public string COURSECODE { get; set; }
    public string COURSENAME { get; set; }
    public string DESCRIPTION { get; set; }
    public int DIS_ORDER { get; set; }
}
[Table("Act_Action")]
public class Action
{
    [Key]
    public Guid ActionId { get; set; }
    public string ActionName { get; set; }
    public int ActionValue { get; set; }
}

Get methods

or a list of all entities in the table.

var entity = await new DapperRepositoryBase<Action>().GetAllAsync();
foreach (var item in entity)
{
    Console.WriteLine(item.ActionId + " " + item.ActionName + " " + item.ActionValue);
}
var course = await new DapperRepositoryBase<Course>().GetAllAsync();
foreach (var item in course)
{
    Console.WriteLine(item.COURSEID + " " + item.COURSENAME);
}

Get one specific entity based on id

var actionId = new Guid("3F4DB83E-4D24-4875-8AC6-D4DA2F5F21B3");
var entity = await new DapperRepositoryBase<Action>().GetAsync(actionId);
if (entity != null)
{
    Console.WriteLine(entity.ActionId + " " + entity.ActionName + " " + entity.ActionValue);
}
var list = await new DapperRepositoryBase<Action>().QueryAsync("select top 1 ActionId,ActionName,ActionValue from Act_Action where ActionId=@ActionId and ActionValue=8", new { ActionId = "66307CAB-3394-4675-8FB3-5A8C90F6CD70" });
if (list != null && list.Count() > 0)
{
    Console.WriteLine("Ok");
}
// 强类型查询
var courseId = 4;
var course = await new DapperRepositoryBase<Course>().QueryAsync("SELECT * FROM TB_COURSE T WHERE COURSEID = :courseId", new { courseId });
foreach (var item in course)
{
    Console.WriteLine(item.COURSEID + " " + item.COURSENAME);
}

Console.Read();
```

**分页查询**

分页采用的Sql

```
SELECT  *
FROM    ( SELECT    row_number() OVER ( ORDER BY ActionValue ) Id ,
                    *
          FROM      ( SELECT    *
                      FROM      Act_Action
                    ) TempA
        ) AS TempInfo
WHERE   Id <= 1 * 2
        AND Id > ( 1 - 1 ) * 2
```

```
var model = new PageInput();
model.OrderStr = "ActionValue";
model.PageIndex = 0;  // 当前索引,第一页
model.PageSize = 2;   // 每页多少条
model.Offset = model.PageIndex * model.PageSize;

var sqlWhere = new System.Text.StringBuilder();
dynamic pms1 = new System.Dynamic.ExpandoObject();
dynamic pms2 = new System.Dynamic.ExpandoObject();

//sqlWhere.Append(" where ActionValue=@ActionValue");
//pms1.ActionValue = 8;

//sqlWhere.Append(" and ActionName like @ActionName");
//pms1.ActionName = string.Format("%{0}%", "查询");

pms2 = pms1;

pms2.OrderStr = model.OrderStr;

var pageOutput = await new DapperRepositoryBase<Action>().GetPageAsync(model, "Act_Action", sqlWhere.ToString(), pms1, pms2) as PageOutput;

var list = new List<Action>();
     foreach (dynamic item in pageOutput.Records)
{
    list.Add(new Action
    {
        ActionId = item.ActionId,
        ActionName = item.ActionName,
        ActionValue = item.ActionValue

    });
}

foreach (var item in list)
{
    Console.WriteLine(item.ActionId + " " + item.ActionName + " " + item.ActionValue);
}
```

##  Insert  methods

```
var action = new Action();
action.ActionName = "删除";
action.ActionValue = 4;

var result = await new DapperRepositoryBase<Action>().InsertAsync(action);
if (result == 0)
{
    Console.WriteLine("添加成功");
}
```

```
var list = new List<Action>();

list.Add(new Action()
{
    ActionName = "编辑",
    ActionValue = 2
});

var count = await new DapperRepositoryBase<Action>().ExecuteAsync("insert into Act_Action(ActionName,ActionValue) values(@ActionName,@ActionValue)", list);
if (count > 0)
{

    Console.WriteLine("成功添加了 {0} 个记录 ", count);
}
else
{
    Console.WriteLine("操作失败,请重试");
}
```

## Delete methods
**a list of entities**

```
var action = new Action();
action.ActionId = new Guid("7ACDAFAF-E3B0-4458-A4F3-6D378F063C52");

var result = await new DapperRepositoryBase<Action>().DeleteAsync(action);
if (result)
{
    Console.WriteLine("删除成功");
}
else
{
    Console.WriteLine("删除失败");
}
```

## Update methods
update a list of entities.

```
// F77F6678-3A7C-4848-94AF-B737A2BC7DD7 编辑 2
// F77F6678-3A7C-4848-94AF-B737A2BC7DD7 导入 64
var action = new Action();
action.ActionId = new Guid("F77F6678-3A7C-4848-94AF-B737A2BC7DD7");
action.ActionName = "导入";
action.ActionValue = 64;

var result = await new DapperRepositoryBase<Action>().UpdateAsync(action);
if (result != null)
{
    Console.WriteLine("更新成功");
}
else
{
    Console.WriteLine("更新失败");
}
```

```
int i = await new DapperRepositoryBase<Action>().ExecuteAsync("update Act_Action set ActionName=@ActionName,ActionValue=@ActionValue where ActionId = @ActionId", new
{
    ActionName = "查询",
    ActionValue = 8,
    ActionId = "66307CAB-3394-4675-8FB3-5A8C90F6CD70"
});

Console.WriteLine("更新了 {0} 条数据", i);
```

## SqlServer连接配置

```
<appSettings>
  <add key="DBProvider" value="System.Data.SqlClient"/>
</appSettings>
<connectionStrings>
  <add name="ConnectionString" connectionString="Server=127.0.0.1;Database=RdfDb;User ID=sa;Password=123456;" providerName="System.Data.SqlClient" />
</connectionStrings>
```

## Oracle连接配置

```
<appSettings>
  <add key="DBProvider" value="System.Data.OracleClient"/>
</appSettings>
<connectionStrings>
  <add name="ConnectionString" connectionString="Data Source=120.0.0.1; User ID=exam;Password=master;" providerName="System.Data.OracleClient"/>
</connectionStrings>
```
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,670评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,928评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,926评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,238评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,112评论 4 356
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,138评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,545评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,232评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,496评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,596评论 2 310
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,369评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,226评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,600评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,906评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,185评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,516评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,721评论 2 335

推荐阅读更多精彩内容

  • 原文地址 Room持久化库 Room为SQLite提供一个抽象层,在充分利用SQLite的同时,允许流畅的数据库访...
    CyrusChan阅读 32,816评论 35 49
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,505评论 18 399
  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 11,946评论 4 60
  • 本文中我们介绍并比较两种最流行的开源持久框架:iBATIS和Hibernate,我们还会讨论到Java Persi...
    大同若鱼阅读 4,283评论 4 27
  • 20世纪初,美国福特公司正处于高速发展时期,一个个车间一片片厂房迅速建成并投入使用。客户的订单快把福特公司销售处的...
    幻无名阅读 227评论 0 1