编辑
2025-02-03
C# 应用
00
请注意,本文编写于 92 天前,最后修改于 92 天前,其中某些信息可能已经过时。

目录

Dapper的特点
1. 轻量级
2. 性能高效
3. 简单明了
4. 灵活性
Dapper的基本用法
环境准备
基本操作示例
1. 创建数据库连接
2. 查询操作
3. 插入操作
4. 更新操作
5. 删除操作
6. 多结果集查询
7. 存储过程
8. 事务支持
9. 映射一对多关系
10. 批量插入
总结

Dapper是一个轻量级的ORM(Object Relational Mapper)工具,专为.NET框架设计,不过个人还是喜欢SqlSugar。它提供了一种高速的,在一定程度上接近手写SQL语句性能的数据库访问方法。它因其简单性和灵活性而广受欢迎,非常适合需要对性能有高要求但又不希望处理复杂的ORM框架,比如Entity Framework的场景。

Dapper的特点

1. 轻量级

Dapper是一个单文件库,集成进项目非常简单,不会像其他大型ORM框架那样增加额外的负担。

2. 性能高效

Dapper直接使用ADO.NET,即其底层仅是对ADO.NET的封装,这保证了非常高的执行效率,几乎与直接使用raw ADO.NET相当。

3. 简单明了

Dapper的API设计简洁易懂,而且它只做必要的工作,绝不过度抽象化。开发者能够在需要时直接编写SQL查询,获取完整的功能控制。

4. 灵活性

由于直接编写SQL语句,Dapper能直接利用数据库特性例如存储过程、复杂查询等,可维护性高,也能与其他ORM框架并行使用。

Dapper的基本用法

环境准备

在开始使用Dapper之前,首先需要确保你的项目中有Dapper这个库。可以使用NuGet包管理器来安装:

PowerShell
Install-Package Dapper

image.png

基本操作示例

1. 创建数据库连接

C#
using System.Data.SqlClient; // Connection string string connectionString = "Server=localhost;Database=testdb;User Id=sa;Password=123;"; // 创建 SQL 连接 using (SqlConnection connection = new SqlConnection(connectionString)) { connection.Open(); // 这里可以进行数据库操作 }

2. 查询操作

Dapper最常用的操作之一是查询数据库。这包括简单的SELECT语句以及复杂的多表JOIN。

C#
using Dapper; using System.Collections.Generic; // 定义数据模型 public class Person { public int Id { get; set; } public string Name { get; set; } public int Age { get; set; } } // 查询数据 string sqlQuery = "SELECT * FROM Person"; using (SqlConnection connection = new SqlConnection(connectionString)) { connection.Open(); IEnumerable<Person> people = connection.Query<Person>(sqlQuery); foreach (var person in people) { Console.WriteLine($"ID: {person.Id}, Name: {person.Name}, Age: {person.Age}"); } }

image.png

3. 插入操作

你还可以使用Dapper进行插入操作:

C#
string insertQuery = "INSERT INTO Person (Name, Age) VALUES (@Name, @Age)"; using (SqlConnection connection = new SqlConnection(connectionString)) { connection.Open(); var affectedRows = connection.Execute(insertQuery, new { Name = "John Doe", Age = 30 }); Console.WriteLine($"Rows inserted: {affectedRows}"); }

4. 更新操作

更新数据库记录同样简单:

C#
string updateQuery = "UPDATE Person SET Age = @Age WHERE Name = @Name"; using (SqlConnection connection = new SqlConnection(connectionString)) { connection.Open(); var affectedRows = connection.Execute(updateQuery, new { Name = "John Doe", Age = 31 }); Console.WriteLine($"Rows updated: {affectedRows}"); }

image.png

5. 删除操作

删除操作也非常直观:

C#
string deleteQuery = "DELETE FROM Person WHERE Name = @Name"; using (SqlConnection connection = new SqlConnection(connectionString)) { connection.Open(); var affectedRows = connection.Execute(deleteQuery, new { Name = "John Doe" }); Console.WriteLine($"Rows deleted: {affectedRows}"); }

6. 多结果集查询

SQL
CREATE PROCEDURE GetPersonAndOrders @PersonId INT AS BEGIN SELECT Id, Name FROM Person WHERE Id = @PersonId SELECT Id, PersonId, Amount FROM [Order] WHERE PersonId = @PersonId END

有时候,我们可能需要从一个查询中获取多个结果集,Dapper可以轻松处理这种情况。

C#
using (SqlConnection connection = new SqlConnection(connectionString)) { connection.Open(); var personIdParameter = new { PersonId = 1 }; // 假设要查询的 PersonId 为 1 using (var multi = connection.QueryMultiple("GetPersonAndOrders", personIdParameter, commandType: CommandType.StoredProcedure)) { var person = multi.Read<Person>().FirstOrDefault(); var orders = multi.Read<Order>().ToList(); if (person != null) { Console.WriteLine($"Person: {person.Name}"); foreach (var order in orders) { Console.WriteLine($"Order ID: {order.OrderId}, Amount: {order.Amount}"); } } else { Console.WriteLine("No person found with the given ID."); } } }

image.png

7. 存储过程

SQL
CREATE PROCEDURE GetPersonById @Id INT AS BEGIN SELECT Id, Name, Age FROM Person WHERE Id = @Id; END

Dapper直接支持调用存储过程,这使得它在使用数据库的内置功能时非常方便。

C#
string storedProcedure = "GetPersonById"; var parameters = new { Id = 1 }; // 假设要查询的人员 ID 为1 using (SqlConnection connection = new SqlConnection(connectionString)) { connection.Open(); try { var person = connection.QueryFirstOrDefault<Person>(storedProcedure, parameters, commandType: CommandType.StoredProcedure); if (person != null) { Console.WriteLine($"Person: {person.Name}, Age: {person.Age}"); } else { Console.WriteLine("No person found with the given ID."); } } catch (SqlException ex) { Console.WriteLine($"SQL Error: {ex.Message}"); } catch (Exception ex) { Console.WriteLine($"An error occurred: {ex.Message}"); } }

image.png

8. 事务支持

Dapper支持数据库事务,可以在多个操作中维护完整性和一致性。

C#
using (SqlConnection connection = new SqlConnection(connectionString)) { connection.Open(); using (var transaction = connection.BeginTransaction()) { try { string insertPersonQuery = "INSERT INTO Person (Name, Age) VALUES (@Name, @Age)"; string insertOrderQuery = "INSERT INTO [Order] (PersonId, Amount) VALUES (@PersonId, @Amount)"; connection.Execute(insertPersonQuery, new { Name = "Jane Doe", Age = 27 }, transaction); connection.Execute(insertOrderQuery, new { PersonId = 2, Amount = 200 }, transaction); transaction.Commit(); Console.WriteLine("Transaction committed successfully."); } catch (Exception ex) { transaction.Rollback(); Console.WriteLine($"Transaction rolled back: {ex.Message}"); } } }

9. 映射一对多关系

C#
public class Person { public int Id { get; set; } public string Name { get; set; } public int Age { get; set; } public List<Order> Orders { get; set; } public Person() { Orders = new List<Order>(); } }

Dapper允许我们在一次查询中映射父/子关系,非常适用于表之间有关系的情况。

C#
string sql = @" SELECT * FROM Person p LEFT JOIN [Order] o ON p.Id = o.PersonId WHERE p.Id = @Id"; using (SqlConnection connection = new SqlConnection(connectionString)) { var lookup = new Dictionary<int, Person>(); connection.Query<Person, Order, Person>(sql, (person, order) => { if (!lookup.TryGetValue(person.Id, out var foundPerson)) { foundPerson = person; foundPerson.Orders = new List<Order>(); lookup.Add(foundPerson.Id, foundPerson); } if (order != null) { foundPerson.Orders.Add(order); } return foundPerson; }, new { Id = 1 }); var result = lookup.Values.FirstOrDefault(); Console.WriteLine($"Person: {result.Name}"); foreach (var order in result.Orders) { Console.WriteLine($"Order ID: {order.OrderId}, Amount: {order.Amount}"); } }

10. 批量插入

虽然Dapper没有直接的批量插入功能,但我们可以通过组合SQL查询或使用数据库特定功能来实现。

C#
var people = new List<Person> { new Person { Name = "Alice", Age = 25 }, new Person { Name = "Bob", Age = 30 } }; string sql = "INSERT INTO Person (Name, Age) VALUES (@Name, @Age)"; using (SqlConnection connection = new SqlConnection(connectionString)) { connection.Open(); var affectedRows = connection.Execute(sql, people); Console.WriteLine($"Rows inserted: {affectedRows}"); }

image.png

这些例子展示了Dapper的强大和灵活性,使其能够应对从简单到复杂的各种数据库操作。无论是处理多结果集、事务、还是关系映射,Dapper都能提供高效的解决方案。

总结

Dapper在保持轻量级和性能优势的同时,提供了强大的数据库交互功能。对于需要高效进行数据库操作但并不适合全栈ORM(如Entity Framework)的项目,Dapper是一个理想的选择。此外,它与其他框架的兼容性,确保了开发者能够灵活地选择最佳的组合工具进行开发。

本文作者:rick

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!