Dapper文档

一,介绍:Dapper是一款轻量级ORM工具。如果你在小的项目中,使用Entity Framework、NHibernate 来处理大数据访问及关系映射,未免有点杀鸡用牛刀。你又觉得ORM省时省力,这时Dapper 将是你不二的选择。

  ---ORM框架的核心思想是对象关系映射,ORM是将表与表之间的操作,映射成对象和对象之间的操作,就是通过操作实体类来达到操作表的目的。从数据库提取的数据会自动按你设置的映射要求封装成特定的对象。之后你就可以通过对对象进行操作来修改数据库中的数据。这时候你面对的不是信息的碎片,而是一个形象鲜明的对象。

二,假如你喜欢原生的Sql语句,又喜欢ORM的简单,那你一定会喜欢上Dapper,这款ROMDapper的优势:

  1. 轻量。只有一个文件(SqlMapper.cs),编译完成之后只有120k(好象是变胖了)
  2. 速度快。Dapper的速度接近与IDataReader,取列表的数据超过了DataTable。
  3. 支持多种数据库。Dapper可以在所有Ado.net Providers下工作,包括sqlite, sqlce, firebird, oracle, MySQL, PostgreSQL and SQL Server
  4. 可以映射一对一,一对多,多对多等多种关系。
  5. 性能高。通过Emit反射IDataReader的序列队列,来快速的得到和产生对象,性能不错。
  6. 支持FrameWork2.0,3.0,3.5,4.0,4.5  

下面介绍Dapper如何使用,来进行高效开发,以下操作是编译后在Net3.5下操作的例子,Net4.0下大部分函数有默认值,参数很简单。

三, 为什么要扩展Dapper?

  了解Dapper都知道,在书写代码时,我们还是会手动写SQL,扩展的目的就是在完全不改变dapper源代码和使用基础上,进行一次封闭,达到零SQL,实现完全对象操作。

四,原生Dapper使用流程:

  0,两种下载使用方法:

  (1),推荐下载方法(使用Nuget下载):

  ---Nuget是一个.NET平台下的开源的项目,它是Visual Studio的扩展。在使用Visual Studio开发基于.NET Framework的应用时,Nuget能把在项目中添加、移除和更新引用的工作变得更加快捷方便。

  

  ---安装成功以后,生成一下网站,项目bin目录下,会生成几个Dapper文件(主要是Dapper.dll,120k)。

  (2),可以在官网上下载Dapper源代码,即SqlMapper.cs文件,在项目中App_Code文件夹中加入这个文件,就像Ado.net中的SqlHelper一样。

  ---源文件地址:https://github.com/StackExchange/dapper-dot-net/blob/master/Dapper%20NET40/SqlMapper.cs

  1,下面可以在项目中开始使用Dapper了

  2,连接数据库字符串。根据不同的数据库进行相应设置,如果是SQL,就类似下边设置;如果是使用SQLite,则设置方法不同。

private readonly string sqlconnection =
"Data Source=RENFB;Initial Catalog=test;User Id=sa;Password=sa;";
//public readonly string mysqlconnectionString =
@"server=127.0.0.1;database=test;uid=renfb;pwd=123456;charset='gbk'";

  3,获取Sql Server的连接数据库对象。

public SqlConnection OpenConnection()
{
    SqlConnection connection = new SqlConnection(sqlconnection);  //这里sqlconnection就是数据库连接字符串
    connection.Open();
    return connection;
}
//获取MySql的连接数据库对象。MySqlConnection
//public MySqlConnection OpenConnection()
//{
//     MySqlConnection connection = new MySqlConnection(mysqlconnectionString);
//     connection.Open();
//     return connection;
//}

  注:如果需要换成Mysql数据库,只用将获得sql Server的连接数据库对象的函数注释掉,取消MySql的连接数据库对象的函数的注释,一并取消Mysql连接字符串的注释,并修改为自己的连接信息。

  Query()方法: Query()是IDbConnection扩展方法并且重载了,从数据库里提取信息,并用来填充我们的业务对象模型。

  4,//先创建一个类,是数据库的user表的模型。
  public class user
     {
        public int id { get; set; }
        public string name { get; set; }
        public string address { get; set; }
        public string age { get; set; }
     }
    5,手写Sql插入数据(增)

    /// <summary>
        /// 手写Sql插入数据
        /// </summary>
        public int InsertWithSql()
        {
            using (var conn = SQLiteHelper.OpenConnection())  //这里访问的是Sqlite数据文件,这里OpenConnection即上边获取连接数据库对象方法
            {
                user user=new user();
                user.name = "Dapper01";
                user.address = "周口";
                user.age="15";
                //string _sql = "INSERT INTO User(name,address,age)VALUES('Dapper01','周口',13)";
                string _sql = "INSERT INTO User(name,address,age)VALUES(@name,@address,@age)";
                return conn.Execute(_sql,user);
            }
        }

    ---如果不用Dapper,用插入一条数据需要多少代码量(相对上边只用了2行代码,下边需要用6行代码):

   public static int insert_news(string title, string content)
    {
        string sql = "insert into news(title,content,addtime) values(@title,@content,@addtime)";
        SQLiteParameter[] parameters =
            {
                SQLiteHelper.MakeSQLiteParameter("@title", DbType.String, title.Trim()),
                SQLiteHelper.MakeSQLiteParameter("@content", DbType.String, content.Trim()),
                SQLiteHelper.MakeSQLiteParameter("@addtime", DbType.DateTime,DateTime.Now)
            };
        return SQLiteHelper.ExecuteSql(sql, parameters);  //调用SQLiteHelper文件中方法,执行数据库插入
    }

6,手写Sql输出数据(删)

protected void Page_Load(object sender, EventArgs e)
        {
            user user = new user();
            user.id = 15;
            DeleteColumn(user);
        }

//删除一个类别(3行):
        public int DeleteColumn(user user)
        {
            using (IDbConnection conn = SQLiteHelper.OpenConnection())
            {
                const string query = "delete from user where id=@id";
                return conn.Execute(query, user);
            }
        }

  ---不用Dapper,删除一条数据,代码如下(4行):

  public static int del_news(string newid)
    {
        string sql = "delete from news where newid=@newid";
        SQLiteParameter[] parameters =
            {
                SQLiteHelper.MakeSQLiteParameter("@newid", DbType.String, newid.Trim())
            };
        return SQLiteHelper.ExecuteSql(sql, parameters);
    }

7,手写Sql更新数据(改)

protected void Page_Load(object sender, EventArgs e)
        {
            user user = new user();
            user.id = 14;
            user.name = "Dapper03";
            user.address = "太康";
            user.age = "25";
            UpdateColumn(user);
        }

//更新一个类别:
        public int UpdateColumn(user user)
        {
            using (IDbConnection conn = SQLiteHelper.OpenConnection())
            {
                const string query = "update user set name=@name,address=@address,age=@age where id=@id";
                return conn.Execute(query, user);
            }
        }

8,手写Sql查询数据(查)

protected void Page_Load(object sender, EventArgs e)
        {
            user user = new user();
            user.id = 14;
            user=SelectColumn(user.id);
            Context.Response.Write(user.name+"|"+user.address+"|"+user.age);
            Context.Response.End();
        }

//获取单个user对象。
        public user SelectColumn(int user_id)
        {
            using (IDbConnection conn = SQLiteHelper.OpenConnection())
            {
                const string query = "select * from user where id=@id";
                return conn.Query<user>(query, new {id = user_id}).SingleOrDefault<user>();  //这里用的是linq语法,所以必须引用System.Linq;
            }
        }

  ---这里我们传递了一个参数给Query方法,参数可以是任何对象,其属性在查询中与sql的参数匹配,由于Query总是返回一个集合,我们只需调用SingleOrDefault方法,因为我们知道总是返回0或1行.

  //获取user对象的集合。
        public IEnumerable<user> SelectUsers()
        {
            using (IDbConnection conn = SQLiteHelper.OpenConnection())
            {
                const string query = "select * from user order by id asc";
                return conn.Query<user>(query, null);
            }
        }

    protected void Page_Load(object sender, EventArgs e)
        {
            IEnumerable<user> list = SelectUsers();
            foreach (var i in list)
            {
                Context.Response.Write(i.name + "|" + i.address + "|" + i.age);
                Context.Response.Write("<br/>");
            }
            Context.Response.End();
        }

五,如果想直接插入一个实体对象,Sql语句都不要了,可以在Nuget上下载Dapper的扩展包--->Dapper.SimpleCRUD安装包。(crud即增查改删)

  ---使用Dapper.SimpleCRUD时,两个注意点,1是直接插入实体,类代码要改:

  public class user
    {
        [Key]    //主键值前加个key
        public int id { get; set; }
        public string name { get; set; }
        public string address { get; set; }
        public string age { get; set; }
    }

       ///<summary>
         ///实体插入数据
         ///</summary>
        public int? InsertWithEntity()
        {
            using (var conn = SQLiteHelper.OpenConnection())
            {
                var user = new user { name = "Dapper02", address = "周口",age="22"};
                return conn.Insert(user);
            }
        } 

  ---2是使用sqlite数据库时,会报错!错误内容如下,因为sqlite不支持scope_identity函数,没有这个函数:

SQL logic error or missing database
no such function: SCOPE_IDENTITY

5,就是这么简单,直接在例子中嵌入Sql,很容易扩展为存储过程,可以使用别名使结果集中的列与业务对象模型(ColumnCat)的属性对应。

//下面使用上面的集合显示出分类。
List<ColumnCat> AllColumnCat =SelectColumnCats().ToList<ColumnCat>();
foreach (ColumnCat cat in AllColumnCat.Where(c => c.Parentid == 0))
{
    Response.Write("Name==>" + cat.Name + "\t");
    Response.Write("时间==>" + cat.ModifiedOn + "\t");
    Response.Write("<br/>");

foreach (ColumnCat c in AllColumnCat
                .Where<ColumnCat>(subColumnCat => subColumnCat.Parentid == cat.Id))
    {
        Response.Write("&nbsp;&nbsp;++++");
        Response.Write("Name==>" + c.Name + "\t");
        Response.Write("时间==>" + c.ModifiedOn + "\t");
        Response.Write("<br/>");
    }
}

//将一级类别和二级类别显示在页面上,如果使用一个递归,很容易实现无限级分类(你懂的)。

7,//Dapper也可以加载填充嵌套对象,考虑这样一种情形,考虑到新闻的类别属性,返回类别对象,
//我们创建一个Column的类
public class Column
{
    public int Id { get; set; }
    public string Name { get; set; }
    public DateTime ModifiedDate { get; set; }
    public ColumnCat ColumnCat { get; set; }
}

//接下来我们来填充我们的业务对象。
public IList<Column> SelectColumnsWithColumnCat()
{
    using (IDbConnection conn = OpenConnection())
    {
        const string query = "select c.Id,c.Name,c.ModifiedDate,c.ColumnCatid
        ,cat.id,cat.[Name],cat.ModifiedOn,cat.Parentid from [Column] as c
        left outer join ColumnCat as cat on c.ColumnCatid=cat.id";
        return conn.Query<Column, ColumnCat, Column>(query
               , (column, columncat) => { column.ColumnCat = columncat; return column; }
               , null, null, false, "Id", null, null).ToList<Column>();
    }
}

  注:1,在填充嵌套对象的时候,只好执行 ToList<>方法,否则回报ExecuteReader 要求已打开且可用的连接。连接的当前状态为已关闭,而单个对象不会报错,估计是using结束后关闭了连接,而嵌套对象在map的时候又执行了 ExecuteReader,只好在using结束之前返回list集合。 2,嵌套对象的参数是比较多的,主要是前两个参数,其它参数没用可以设置为null,不过在4.0版本可以只写两个参数,其它参数都有默认值。特别要注意 的是splitOn,这个参数不能为空,否则会报对象为引用的错误。【splitOn参数的意思是读取第二个对象的的分割列,从哪个列起开始读取第二个对 象,如果表里的自增长列都为Id,可以设置这个参数为”Id”】.

  Execute方法: 正如Query方法是检索数据的,Execute方法不会检索数据,它与Query方法非常相似,但它总返回总数(受影响的行数),而不是一个对象集合【如:insert update和delete】.

8,//接下来向数据库里添加一个类别
public int InsertColumnCat(ColumnCat cat)
{
    using (IDbConnection conn = OpenConnection())
    {
        const string query = "insert into ColumnCat([name],ModifiedOn,Parentid)
        values (@name,@ModifiedOn,@Parentid)";
        int row = conn.Execute(query,cat);
        //更新对象的Id为数据库里新增的Id,假如增加之后不需要获得新增的对象,
        //只需将对象添加到数据库里,可以将下面的一行注释掉。
        SetIdentity(conn,id=>cat.Id=id,"id","ColumnCat");    
        return row;
    }
}
 
public void SetIdentity(IDbConnection conn, Action<int> setId,string primarykey
                          ,string tableName)
{
    if (string.IsNullOrEmpty(primarykey)) primarykey = "id";
    if (string.IsNullOrEmpty(tableName))
    {
        throw new ArgumentException("tableName参数不能为空,为查询的表名");
    }
    string query = string.Format("SELECT max({0}) as Id FROM {1}", primarykey
                         , tableName);
    NewId identity = conn.Query<NewId>(query, null).Single<NewId>();
    setId(identity.Id);
}

public class NewId
{
    public int Id { get; set; }
}

  由于Dapper是通过类的属性自动绑定的,所以增 加了NewId类来获取增加对象后的Id,本来打算使用@@identity,Net3.5下使用总是报错,只好使用Max函数获取。当然如果不需要获得 更新后的对象的ID,可以不使用SetIdentity,这个函数通用。

编译Dapper源码生成的是Net4.0下使用的,可以借助Net4.0新增的dynamic动态类型,
//SetIdentity的实现将非常方便。如下:
public void SetIdentity<T>(IDbConnection conn, Action<int> setId)
{
    dynamic identity = connection.Query("SELECT @@IDENTITY AS Id").Single();
    T newId = (T)identity.Id;
    setId(newId);
}
9,下面介绍一下Dapper的高级用法 
//Dapper对事务处理的例子,如删除类别的同时删除类别下的所有新闻。或者删除产品的同时,
//删除产品图片表里关联的所有图片。
public int DeleteColumnCatAndColumn(ColumnCat cat)
{
    using (IDbConnection conn = OpenConnection())
    {
        const string deleteColumn = "delete from [Column] where ColumnCatid=@catid";
        const string deleteColumnCat = "delete from ColumnCat where id=@Id";

IDbTransaction transaction = conn.BeginTransaction();
        int row=conn.Execute(deleteColumn, new { catid =cat.Id},transaction,null,null);
        row += conn.Execute(deleteColumnCat, new { id=cat.Id},transaction,null,null);
        transaction.Commit();
        return row;
    }
}


原文地址:https://www.cnblogs.com/feichengwulai/articles/4277100.html

Dapper简介的更多相关文章

  1. ORM系列之三:Dapper

    目录 1.Dapper 简介 2.Dapper 安装 3.Dapper 使用 Dapper简介 Dapper是一个轻量级的ORM框架,短小精悍,正如其名.对于小项目,使用EF,NHibernate这样 ...

  2. Dapper.Rainbow 简单使用

    一.  Dapper 简介        一个效率比较高的微型ORM.   二 . Dapper.Rainbow        Dapper的扩展,在这个扩展里面实现了 Dynamic 的 插入和更新 ...

  3. C# Dapper 轻量ORM调试对SQLServer

    Dapper简介 Dapper只有一个代码文件,完全开源,你可以放在项目里的任何位置,来实现数据到对象的ORM操作,体积小速度快. 使用ORM的好处是增.删.改很快,不用自己写sql,因为这都是重复技 ...

  4. ASP.NET Core 中的 ORM 之 Dapper

    目录 Dapper 简介 使用 Dapper 使用 Dapper Contrib 或其他扩展 引入工作单元 Unit of Work 源代码 参考 Dapper 简介 Dapper是.NET的一款轻量 ...

  5. 轻量级ORM框架Dapper应用一:Dapper安装

    一.Dapper简介 Dapper是一款轻量级ORM框架,为解决网站访问流量极高而产生的性能问题而构造,主要通过执行TSQL表达式而实现数据库的CQRS. 如果你在项目中遇到性能访问问题,选择Dapp ...

  6. Dapper(一) 简介和性能

    Dapper的简介 Dapper是.NET下一个micro的ORM,它和Entity Framework或Nhibnate不同,属于轻量级的,并且是半自动的.Dapper只有一个代码文件,完全开源,你 ...

  7. 自制简单的.Net ORM框架 (一) 简介

    在自己研究ORM之前,也使用过几个成熟的ORM方案,例如:EntityFramework,PetaPoco,Dapper 等,用是很好用,但是对自己来说总是不那么方便,EF比较笨重,Dapper要自定 ...

  8. ORM之PetaPoco入门(一)--Petapoco简介

    1. ORM概括 1.1. ORM简介 ORM 对象-关系映射(Object/Relation Mapping,简称ORM),是随着面向对象的软件开发方法发展而产生的.面向对象的开发方法是当今企业级应 ...

  9. 超轻量级高性能ORM数据访问组件Deft,比dapper快20%以上

    超轻量级高性能ORM数据访问组件Deft,比dapper快20%以上 阅读目录 Deft简介 Deft 核心类介绍 Deft 3分钟即可上手使用 其他可选的配置参数 性能测试 Demo代码下载 回到顶 ...

随机推荐

  1. 论文阅读笔记(十九)【ITIP2017】:Super-Resolution Person Re-Identification With Semi-Coupled Low-Rank Discriminant Dictionary Learning

    Introduction (1)问题描述: super resolution(SP)问题:Gallery是 high resolution(HR),Probe是 low resolution(LR). ...

  2. get请求与post请求中文乱码问题的解决办法

    首先出现中文乱码的原因是tomcat默认的编码方式是"ISO-8859-1",这种编码方式以单个字节作为一个字符,而汉字是以两个字节表示一个字符的. 一,get请求参数中文乱码的解 ...

  3. Don't assign one object to another one

    correct way, when changing object, firstly you should create this object and then assign its propert ...

  4. css样式的兼容性

    浏览器                 前缀 IE和safari             -webkit- Chrome                -ms- Firefox            ...

  5. javaweb利用javabean将数据库中内容遍历在页面输出

    效果如下图 它所实现的就是把数据库中一个表中所有的数据一条一条以表格的形式输出在网页上, 实现方法如下 首先我们要从数据库读取数据,这里要借助javabean来方便我们传递数据 以上面的为例,我要输出 ...

  6. PAT (Advanced Level) Practice 1035 Password (20 分)

    To prepare for PAT, the judge sometimes has to generate random passwords for the users. The problem ...

  7. linux--后端项目部署

    nginx + uwsgi + crm + mysql + virtualenv + supervisor项目部署 1.后端整起,用uwsgi启动crm 2.创建一个新的虚拟环境,用于运行crm新业务 ...

  8. upload-labs打关详解

    1-19关 00x01 JS检查 方法一.修改javascript代码,将.php添加到允许上传的类型中 3.上传成功 方法二:绕过前端,通过burpsuit抓包,上传一张info.jpg图片,然后抓 ...

  9. vim光标操作

    v可视模式 ve可视模式但不包括selection o操作符等待模式 i插入模式 r替换模式(命令模式下,按r,输入一个字符将替换光标所在处字符) c命令行常规模式 ci命令行插入模式 cr命令行替换 ...

  10. centos7在命令界面使用命令可以执行,但在jenkins中输入命令报Chrome has crashed.

    问题:selenium.common.exceptions.WebDriverException: Message: unknown error: Chrome failed to start: ex ...