Dapper簡明教程


轉自:http://www.cnblogs.com/Leo_wl/p/5863066.html

   Dapper是一款輕量級的ORM框架,有關Dapper優缺點的文章網上一大堆,這里小編就不再贅述啦。下面直接進入正題:

使用前准備

添加對Dapper的引用

  在使用Dapper之前,我們要首先添加對Dapper的引用,這里小編使用NuGet來添加引用。因為小編使用的是MySQL數據庫,所以也要在項目中添加對MySql.Data的引用。

  Dapper是一款ORM框架,用於數據表和實體模型間的映射,所以在使用前我們還需要創建數據表和實體模型。

創建數據表

復制代碼
復制代碼
CREATE TABLE `t_schools` (
`Id`  int(11) NOT NULL AUTO_INCREMENT ,
`Name`  varchar(20)  NOT NULL ,
`Address`  varchar(50)  NOT NULL ,
PRIMARY KEY (`Id`)
)

CREATE TABLE `t_students` (
`Id`  int(11) NOT NULL AUTO_INCREMENT ,
`Name`  varchar(15) NOT NULL ,
`Number`  varchar(15)  NOT NULL ,
`SchoolId`  int(11) NOT NULL ,
`Gender`  enum('男','女','保密') NOT NULL ,
PRIMARY KEY (`Id`)
)
復制代碼
復制代碼

創建模型

復制代碼
復制代碼
class School
{
    /*
      若屬性名和數據庫字段不一致則查詢不出數據,如果使用EF則可以通過Column特性
      建立屬性和數據表字段之間的映射關系,Dapper則不行
    */
    //[Column("Name")]
    public string Title { set; get; }
    public string Address { set; get; }
}

class Student
{
    public string Name { set; get; }
    public string Number { set; get; }
    public int SchoolId { set; get; }
}
復制代碼
復制代碼

Dapper的基本用法

復制代碼
復制代碼
const string _connectionString = "Database=Dapper;Data Source=127.0.0.1;User Id=root;Password=root;pooling=false;CharSet=utf8;port=3306;";
using (IDbConnection dbConnection = new MySqlConnection(_connectionString))
{
    dbConnection.Open();
    //通過匿名類型插入單條數據
    dbConnection.Execute("insert into t_schools(Name,Address) values(@Name,@Address)", new { Name = "西南大學", Address = "重慶市北碚區天生路2號" });
    //批量插入數據
    List<School> schools = new List<School>()
    {
      new School() {Address="China·BeiJing",Title="清華大學" },
      new School() {Address="杭州",Title="浙江大學" },
      new School() {Address="不知道,US?",Title="哈弗大學" }
    };
    //在執行參數化的SQL時,SQL中的參數(如@title可以和數據表中的字段不一致,但要和實體類型的屬性Title相對應)
    dbConnection.Execute("insert into t_schools(Address,Name) values(@address,@title);", schools);
    //通過匿名類型批量插入數據
    dbConnection.Execute("insert into t_schools(Address,Name) values(@address,@name)", 
    new[] {
      new {Address="楊浦區四平路1239號",Name="同濟大學"},
      new {Address="英國",Name="劍橋"},
      new {Address="美國·硅谷",Name="斯坦福大學"}
    });
}
復制代碼
復制代碼

使用Dapper進行查詢操作

  默認情況下Dapper會將查詢到的整個數據集放到內存中,可以在Query方法中通過參數buffered來設置是否將查詢結果存放到內存中

查詢結果映射到強類型

復制代碼
var schools = dbConnection.Query<School>("select * from t_schools where Name=@name", new { Name = "西南大學" });
foreach (var school in schools)
{
    Console.WriteLine(school.Address);
}
復制代碼

查詢變量如下圖:

  
  有上圖我們可以看到,因為School類中的Title屬性在數據庫中沒有與之對應的字段,所以Title的值為null。查詢結果見下圖:

 

查詢結果映射到匿名類型

  在上面的查詢中,我們將查詢結果映射到了自定義的類型上。除了將查詢結果映射到強類型之外,Dapper中還提供了匿名查詢方式。

復制代碼
復制代碼
//查詢結果result是匿名類型
var result = dbConnection.Query("select * from t_schools limit 0,3");
var resultList = result.AsList();
foreach (var l in resultList)
{
    Console.WriteLine(l.Name);
}
復制代碼
復制代碼

查詢結果如下:

 

in

復制代碼
復制代碼
var result = dbConnection.Query<Student>("select * from t_students where SchoolId in @schoolId", new { schoolId = new int[] { 2, 3 } });
foreach (var r in result)
{
    var ps = r.GetType().GetProperties();
    foreach (var p in ps)
    {
        Console.Write(p.Name + "=" + p.GetValue(r) + " ");
    }
    Console.WriteLine();
}
復制代碼
復制代碼

查詢結果如下:

 

between

復制代碼
復制代碼
var result = dbConnection.Query<School>("select Name,Address from t_schools where Id between @start and @end", new { start = 2, end = 4 });
foreach (var r in result)
{
    var ps = r.GetType().GetProperties();
    foreach (var p in ps)
    {
        Console.Write(p.Name + "=" + p.GetValue(r) + " ");
    }
    Console.WriteLine();
}
復制代碼
復制代碼

 查詢結果如下:

 

join

  使用join查詢時需要用到Query方法中的splitOn參數,話說這個參數讓小編糾結了很久才弄明白。關於splitOn參數的說明,可參考stackoverflow上的一篇文章Correct use of Multimapping in Dapper

復制代碼
復制代碼
var result = dbConnection.Query<Student, School, string>("select s.Name,sc.Address from t_students s,t_schools sc where s.SchoolId=sc.Id and binary sc.Address like '%BeiJing%'",
    (s, sc) =>
    {
        return s.Name + " " + sc.Address;
    }, 
    /*
    還有一點需要特別注意,泛型參數的順序必須和SQL語句查詢數據表的順序一致,
    即Student對應t_students表的查詢結果s.Name,否則Query方法的查詢結果
    可能為null(這點也是困擾小編很久......)
    */
    splitOn: "Address"
    );
foreach (var r in result)
{
    Console.WriteLine(r);
}
復制代碼
復制代碼

查詢結果如下:

Dapper執行多條SQL語句

復制代碼
復制代碼
string sql = "select Address from t_schools;select SchoolId from t_students;select Name from t_students";
using (var multipleReader = dbConnection.QueryMultiple(sql))
{
    //一次執行N條SQL語句則最多只能調用N次Read方法,否則拋異常:the reader has been disposed.
    //Dapper讀取查詢結果數據的順序必須要和查詢語句中的查詢順序一致,否則可能讀取不到數據
    var schoolList = multipleReader.Read<School>();
    foreach (var s in schoolList)
    {
        Console.Write(s.Address + " ");
    }
    Console.WriteLine();
    var studentSchools = multipleReader.Read<Student>();
    foreach (var s in studentSchools)
    {
        Console.Write(s.SchoolId + " ");
    }
    Console.WriteLine();
    var studentNames = multipleReader.Read<Student>();
    foreach (var s in studentNames)
    {
        Console.Write(s.Name + " ");
    }
}
復制代碼
復制代碼

查詢結果如下:

事務

使用Dapper執行事務倒是沒有什么需要特別說明的。

復制代碼
復制代碼
using (IDbTransaction tran = dbConnection.BeginTransaction())
{
    try
    {
        dbConnection.Execute("delete from t_schools where Id=3");
        throw new Exception();
        tran.Commit();
    }
    catch
    {
        tran.Rollback();
    }
}
復制代碼
復制代碼

存儲過程

首先先創建一個存儲過程

復制代碼
DROP PROCEDURE IF EXISTS `GetSchoolName`;
CREATE PROCEDURE `GetSchoolName`(in schoolId int,out scname varchar(20))
BEGIN
select `Name` into scname from t_schools where Id=schoolId;
select scname; 
END;
復制代碼

然后在程序中調用存儲過程

復制代碼
//在程序中調用存儲過程時,存儲過程名要小寫,傳遞的參數名要和存儲過程中的參數名一致(不區分大小寫)
//連接字符串中的數據庫名也要小寫,否則拋異常:在數據庫***中找不到存儲過程×××
var parameters = new DynamicParameters();
parameters.Add("@scname", dbType: DbType.String, direction: ParameterDirection.Output);
parameters.Add("schoolid", 6, direction: ParameterDirection.Input);
var result = dbConnection.Query("getschoolname", parameters, commandType: CommandType.StoredProcedure);
復制代碼

執行結果如下:

從上圖可以看出,返回值類型是Dapper中定義的DapperRow類型。

結語

  • Dapper是一個輕量級的ORM框架,它是通過擴展IDbConnection接口來實現一系列的功能的。相比EF、NHibernate,它的功能較為簡單。
  • Dapper在執行查詢語句時會緩存SQL語句的相關信息,這樣就保證了Dapper擁有較高的性能(原文:Dapper caches information about every query it runs, this allow it to materialize objects quickly and process parameters quickly)。

以上內容是小編自己的一個學習總結,寫出來一是作為自己的學習筆記,二是和廣大網友分享。文中若有錯誤之處,還望各位讀者能夠指正。

參考文章:

Dapper
Dapper快速學習
Dapper中的一些復雜操作和inner join應該注意的坑
Dapper異常匯總
Correct use of Multimapping in Dapper


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM