Dapper是什么?
Dpper是一款.Net平台簡單(Simple)的對象映射庫,並且Dapper擁有着“微型ORM之王”的稱號。就速度而言與手寫ADO.NET SqlDateReader相同。ORM是Object Relational Mapper的縮寫,代表着數據庫與編程語言之間的映射。
Dapper的基本特性是通過擴展IDbConnection 接口,並為其提供查詢數據庫的方法。
Dapper是如何工作的?
將大象裝冰箱總共分三步,Dapper也是如此。
- 創建IDBConnection對象(例如:SqlConnection)
- 編寫用於CRUD的Sql語句
- 將Sql語句當作參數純如執行操作的方法
安裝
通過NuGet安裝:https://www.nuget.org/packages/Dapper
PM> Install-Package Dapper
方法表
Dapper會用多個方法去擴展IDBConnection接口
- Execute
- Query
- QueryFirst
- QueryFirstOrDefault
- QuerySingle
- QuerySingleOrDefault
- QueryMultiple
string sqlInvoices = "SELECT * FROM Invoice;"; string sqlInvoice = "SELECT * FROM Invoice WHERE InvoiceID = @InvoiceID;"; string sp = "EXEC Invoice_Insert"; using (var connection = My.ConnectionFactory()) { var invoices = connection.Query<Invoice>(sqlInvoices).ToList(); var invoice = connection.QueryFirstOrDefault(sqlInvoice, new {InvoiceID = 1}); var affectedRows = connection.Execute(sp, new { Param1 = "Single_Insert_1" }, commandType: CommandType.StoredProcedure); }
參數表
有多種不同的方式給“查詢(例如:select)”和“執行(例如:delete、update、insert)”方法傳遞參數
- Anonymous
- Dynamic
- List
- String
// 匿名類對象(相對比較常用) var affectedRows = connection.Execute(sql, new {Kind = InvoiceKind.WebInvoice, Code = "Single_Insert_1"}, commandType: CommandType.StoredProcedure); // Dynamic DynamicParameters parameter = new DynamicParameters(); parameter.Add("@Kind", InvoiceKind.WebInvoice, DbType.Int32, ParameterDirection.Input); parameter.Add("@Code", "Many_Insert_0", DbType.String, ParameterDirection.Input); parameter.Add("@RowCount", dbType: DbType.Int32, direction: ParameterDirection.ReturnValue); connection.Execute(sql, new {Kind = InvoiceKind.WebInvoice, Code = "Single_Insert_1"}, commandType: CommandType.StoredProcedure); // List connection.Query<Invoice>(sql, new {Kind = new[] {InvoiceKind.StoreInvoice, InvoiceKind.WebInvoice}}).ToList(); // String connection.Query<Invoice>(sql, new {Code = new DbString {Value = "Invoice_1", IsFixedLength = false, Length = 9, IsAnsi = true}}).ToList();
結果集
查詢方法的返回值可以映射成多種類型
- Anonymous
- Strongly Typed
- Multi-Mapping
- Multi-Result
- Multi-Type
string sql = "SELECT * FROM Invoice;"; using (var connection = My.ConnectionFactory()) { connection.Open(); var anonymousList = connection.Query(sql).ToList(); var invoices = connection.Query<Invoice>(sql).ToList(); }
Utilities
- Async
- Buffered
- Transaction
- Stored Procedure
// Async connection.QueryAsync<Invoice>(sql) // Buffered connection.Query<Invoice>(sql, buffered: false) // Transaction using (var transaction = connection.BeginTransaction()) { var affectedRows = connection.Execute(sql, new {Kind = InvoiceKind.WebInvoice, Code = "Single_Insert_1"}, commandType: CommandType.StoredProcedure, transaction: transaction); transaction.Commit(); } // Stored Procedure var affectedRows = connection.Execute(sql, new {Kind = InvoiceKind.WebInvoice, Code = "Single_Insert_1"}, commandType: CommandType.StoredProcedure);
執行非查詢語句
描述
你可以從任意實現IDbConnection的類對象中調用Dapper的擴展方法“Execute”。它能夠執行一條命令(Command)一次或者多次,並返回受影響的行數。這個方法通常用來執行:
- Stored Procedure
- INSERT statement
- UPDATE statement
- DELETE statement
參數
下面表格中顯示了Execute方法的不同參數
| 名稱 | 描述 |
|---|---|
| sql | 要執行的sql語句文本 |
| param | command的參數 |
| transaction | 事務 |
| commandTimeout | command超時時間 |
| commandType | command類型 |
示例:執行存儲過程
單次
執行存儲過程一次
string sql = "EXEC Invoice_Insert";
using (var connection = My.ConnectionFactory()) { connection.Open(); var affectedRows = connection.Execute(sql, new {Kind = InvoiceKind.WebInvoice, Code = "Single_Insert_1"}, commandType: CommandType.StoredProcedure); My.Result.Show(affectedRows); }

多次
執行存儲過程多次,數組中的每條數據都執行一次
string sql = "EXEC Invoice_Insert";
using (var connection = My.ConnectionFactory()) { connection.Open(); var affectedRows = connection.Execute(sql, new[] { new {Kind = InvoiceKind.WebInvoice, Code = "Many_Insert_1"}, new {Kind = InvoiceKind.WebInvoice, Code = "Many_Insert_2"}, new {Kind = InvoiceKind.StoreInvoice, Code = "Many_Insert_3"} }, commandType: CommandType.StoredProcedure ); My.Result.Show(affectedRows); }
示例:執行插入
單次
執行插入語句一次
string sql = "INSERT INTO Invoice (Code) Values (@Code);";
using (var connection = My.ConnectionFactory()) { connection.Open(); var affectedRows = connection.Execute(sql, new {Kind = InvoiceKind.WebInvoice, Code = "Single_Insert_1"}); My.Result.Show(affectedRows); }
多次
執行多次,數組中的每條數據都執行一次
string sql = "INSERT INTO Invoice (Code) Values (@Code);";
using (var connection = My.ConnectionFactory()) { connection.Open(); var affectedRows = connection.Execute(sql, new[] { new {Kind = InvoiceKind.WebInvoice, Code = "Many_Insert_1"}, new {Kind = InvoiceKind.WebInvoice, Code = "Many_Insert_2"}, new {Kind = InvoiceKind.StoreInvoice, Code = "Many_Insert_3"} } ); My.Result.Show(affectedRows); }
示例:執行Update
單次
執行Update語句一次
string sql = "UPDATE Invoice SET Code = @Code WHERE InvoiceID = @InvoiceID";
using (var connection = My.ConnectionFactory()) { connection.Open(); var affectedRows = connection.Execute(sql, new {InvoiceID = 1, Code = "Single_Update_1"}); My.Result.Show(affectedRows); }
多次
執行多次,數組中的每條數據都執行一次。
string sql = "UPDATE Invoice SET Code = @Code WHERE InvoiceID = @InvoiceID";
using (var connection = My.ConnectionFactory()) { connection.Open(); var affectedRows = connection.Execute(sql, new[] { new {InvoiceID = 1, Code = "Many_Update_1"}, new {InvoiceID = 2, Code = "Many_Update_2"}, new {InvoiceID = 3, Code = "Many_Update_3"} }); My.Result.Show(affectedRows); }
示例:執行Delete
單次
執行Delete語句一次
string sql = "DELETE FROM Invoice WHERE InvoiceID = @InvoiceID";
using (var connection = My.ConnectionFactory()) { connection.Open(); var affectedRows = connection.Execute(sql, new {InvoiceID = 1}); My.Result.Show(affectedRows); }
多次
執行多次,數組中的每條數據都執行一次
string sql = "DELETE FROM Invoice WHERE InvoiceID = @InvoiceID";
using (var connection = My.ConnectionFactory()) { connection.Open(); var affectedRows = connection.Execute(sql, new[] { new {InvoiceID = 1}, new {InvoiceID = 2}, new {InvoiceID = 3} }); }
Dapper Query查詢
介紹
查詢方法(Query)是IDbConnection的擴展方法,它可以用來執行查詢(select)並映射結果到C#實體(Model、Entity)類
查詢結果可以映射成如下類型:
- Anonymous 匿名類型
- Strongly Typed 強類型
- Multi-Mapping (One to One) 多映射 一對一
- Multi-Mapping (One to Many) 多映射 一對多
- Multi-Type 多類型
參數
下面表格中顯示了Query方法的不同參數
| 名稱 | 描述 |
|---|---|
| sql | 要執行的sql語句文本 |
| param | command的參數 |
| transaction | 事務 |
| buffered | True to buffer readeing the results of the query (default = true). 翻譯不來。。。 |
| commandTimeout | command超時時間 |
| commandType | command類型
|
示例 - 匿名查詢
Raw SQL query can be executed using Query method and map the result to a dynamic list.
直接執行SQL語句字符串,然后將結果映射成 dynamic類型的List中
string sql = "SELECT * FROM Invoice;";
using (var connection = My.ConnectionFactory()) { connection.Open(); var invoices = connection.Query(sql).ToList(); My.Result.Show(invoices); }

示例 - 強類型查詢(最常用)
直接執行SQL語句字符串,然后將結果映射成強類型類型的List中
string sql = "SELECT * FROM Invoice;";
using (var connection = My.ConnectionFactory()) { connection.Open(); var invoices = connection.Query<Invoice>(sql).ToList(); My.Result.Show(invoices); }

示例 - 多映射查詢 (One to One)
Raw SQL query can be executed using Query method and map the result to a strongly typed list with a one to one relation.(沒太理解)
直接執行SQL語句字符串,然后將結果用一對一的關系映射成強類型類型的List中
string sql = "SELECT * FROM Invoice AS A INNER JOIN InvoiceDetail AS B ON A.InvoiceID = B.InvoiceID;";
using (var connection = My.ConnectionFactory()) { connection.Open(); var invoices = connection.Query<Invoice, InvoiceDetail, Invoice>( sql, (invoice, invoiceDetail) => { invoice.InvoiceDetail = invoiceDetail; return invoice; }, splitOn: "InvoiceID") .Distinct() .ToList(); My.Result.Show(invoices); }

示例 - 查詢多映射 (One to Many)
Raw SQL query can be executed using Query method and map the result to a strongly typed list with a one to many relations.
直接執行SQL語句字符串,然后將結果用一對多的關系映射成強類型類型的List中
string sql = "SELECT * FROM Invoice AS A INNER JOIN InvoiceItem AS B ON A.InvoiceID = B.InvoiceID;";
using (var connection = My.ConnectionFactory()) { connection.Open(); var invoiceDictionary = new Dictionary<int, Invoice>(); var invoices = connection.Query<Invoice, InvoiceItem, Invoice>( sql, (invoice, invoiceItem) => { Invoice invoiceEntry; if (!invoiceDictionary.TryGetValue(invoice.InvoiceID, out invoiceEntry)) { invoiceEntry = invoice; invoiceEntry.Items = new List<InvoiceItem>(); invoiceDictionary.Add(invoiceEntry.InvoiceID, invoiceEntry); } invoiceEntry.Items.Add(invoiceItem); return invoiceEntry; }, splitOn: "InvoiceID") .Distinct() .ToList(); My.Result.Show(invoices); }

示例 - Query Multi-Type
Raw SQL query can be executed using Query method and map the result to a list of different types.
string sql = "SELECT * FROM Invoice;";
using (var connection = My.ConnectionFactory()) { connection.Open(); var invoices = new List<Invoice>(); using (var reader = connection.ExecuteReader(sql)) { var storeInvoiceParser = reader.GetRowParser<StoreInvoice>(); var webInvoiceParser = reader.GetRowParser<WebInvoice>(); while (reader.Read()) { Invoice invoice; switch ((InvoiceKind) reader.GetInt32(reader.GetOrdinal("Kind"))) { case InvoiceKind.StoreInvoice: invoice = storeInvoiceParser(reader); break; case InvoiceKind.WebInvoice: invoice = webInvoiceParser(reader); break; default: throw new Exception(ExceptionMessage.GeneralException); } invoices.Add(invoice); } } My.Result.Show(invoices); }

參考文章:
