轻量高效的ORM利器:Dapper在C#中的实践指南

轻量高效的ORM利器:Dapper在C#中的实践指南

编码文章call10242025-09-03 22:14:158A+A-

Dapper是由Stack Overflow团队开发的轻量级ORM库,专注于高性能数据库操作。与传统ORM(如Entity Framework)相比,Dapper通过扩展IDbConnection接口提供极简API,在保持代码简洁的同时,性能接近原生ADO.NET。其核心优势在于零配置映射、执行速度快(比EF快2-10倍),特别适合高并发场景。

一、Dapper的核心特点

  1. 高性能
    动态生成IL代码映射查询结果到对象,消除反射开销。
  2. 轻量级
    仅15个核心方法(如
    Query, Execute),无复杂跟踪机制。
  3. 类型安全
    强类型参数和返回值,支持泛型。
  4. 直接SQL控制
    开发者完全掌控SQL语句,避免ORM自动生成低效查询。
  5. 多数据库支持
    兼容SQL Server、MySQL、SQLite等(需配合对应ADO.NET驱动)。

二、Dapper的实现原理

1. 扩展方法模式

public static IEnumerable<T> Query<T>(
    this IDbConnection cnn, 
    string sql, 
    object param = null, 
    IDbTransaction transaction = null, 
    bool buffered = true)
  • 通过扩展IDbConnection添加新方法,无缝集成现有ADO.NET代码。

2. 动态代码生成

  • 首次查询时生成IL代码实现属性映射,后续调用直接使用编译后的委托,避免反射性能损耗。

3. 参数化查询

自动将匿名对象转换为DbParameter,防止SQL注入:

var user = conn.Query<User>("SELECT * FROM Users WHERE Id = @Id", new { Id = 1 });

三、C#实战示例

环境准备

  1. 安装NuGet包:
Install-Package Dapper
Install-Package System.Data.SQLite // 以SQLite为例

步骤1:定义实体类

public class User
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Email { get; set; }
}

public class Order
{
    public int OrderId { get; set; }
    public int UserId { get; set; }
    public decimal Amount { get; set; }
}

步骤2:基础CRUD操作

using (var conn = new SQLiteConnection("Data Source=test.db"))
{
    conn.Open();
    
    // 插入数据(返回自增ID)
    var newId = conn.ExecuteScalar<int>(
        "INSERT INTO Users (Name, Email) VALUES (@Name, @Email); SELECT last_insert_rowid();",
        new { Name = "Alice", Email = "alice@example.com" });
    
    // 查询单条记录
    var user = conn.QueryFirstOrDefault<User>(
        "SELECT * FROM Users WHERE Id = @Id", 
        new { Id = newId });
    
    // 更新操作
    var rowsAffected = conn.Execute(
        "UPDATE Users SET Email = @NewEmail WHERE Id = @Id",
        new { NewEmail = "alice2@example.com", Id = newId });
    
    // 查询列表
    var users = conn.Query<User>("SELECT * FROM Users WHERE Name LIKE '%a%'");
}

步骤3:多表关联查询(一对多映射)

var sql = @"
    SELECT u.*, o.*
    FROM Users u 
    INNER JOIN Orders o ON u.Id = o.UserId
    WHERE u.Id = @UserId";

var users = conn.Query<User, Order, User>(
    sql,
    (user, order) => 
    {
        user.Orders ??= new List<Order>();
        user.Orders.Add(order);
        return user;
    },
    new { UserId = 1 },
    splitOn: "OrderId" // 分割列名
).Distinct().ToList();

// 实体类补充:
public class User
{
    // ...原有属性
    public List<Order> Orders { get; set; }
}

步骤4:事务处理

using (var trans = conn.BeginTransaction())
{
    try
    {
        conn.Execute(
            "INSERT INTO Orders (UserId, Amount) VALUES (@UserId, @Amount)",
            new { UserId = 1, Amount = 99.99m },
            trans);
        
        conn.Execute(
            "UPDATE Users SET LastOrderDate = @Date WHERE Id = @Id",
            new { Date = DateTime.Now, Id = 1 },
            trans);
            
        trans.Commit();
    }
    catch
    {
        trans.Rollback();
        throw;
    }
}

步骤5:批量操作

var users = new List<User>
{
    new User { Name = "Bob", Email = "bob@test.com" },
    new User { Name = "Charlie", Email = "charlie@test.com" }
};

conn.Execute(
    "INSERT INTO Users (Name, Email) VALUES (@Name, @Email)",
    users); // 自动遍历集合执行

四、性能优化技巧

  1. 异步操作
    使用
    QueryAsync避免线程阻塞:
var users = await conn.QueryAsync<User>("SELECT * FROM Users");
  1. 参数复用
    预编译参数对象提升重复查询性能。
  2. 结果缓冲
    大数据集时关闭缓冲(
    buffered: false)减少内存占用:
var unbufferedUsers = conn.Query<User>("SELECT * FROM Users", buffered: false);

结语

Dapper以极简设计+极致性能成为.NET高性能数据库访问的首选。虽然需要手动编写SQL,但其直观的API和灵活的映射机制,特别适合追求性能的开发者。

点击这里复制本文地址 以上内容由文彬编程网整理呈现,请务必在转载分享时注明本文地址!如对内容有疑问,请联系我们,谢谢!
qrcode

文彬编程网 © All Rights Reserved.  蜀ICP备2024111239号-4