Dapper作为轻量级的ORM框架,不需要复杂的配置就能快速实现C#程序与数据库的交互,相比原生ADO.NET减少了大量重复的代码编写工作,同时保留了接近原生SQL的执行性能。

Dapper环境准备
首先需要在项目中引入Dapper依赖,如果你使用的是.NET Core或者.NET 5及以上版本,可以通过NuGet包管理器安装Dapper,也可以在项目文件里添加对应的PackageReference。安装完成后就可以在代码中引用Dapper的命名空间使用相关功能。
以下是.NET项目中添加Dapper依赖的配置示例:
<PackageReference Include="Dapper" Version="2.1.35" />
数据库连接配置
使用Dapper之前需要先建立数据库连接,Dapper本身不管理连接池,需要配合ADO.NET的数据库连接对象使用。首先需要在配置文件中配置数据库连接字符串,然后编写获取连接对象的方法。
以下是获取SQL Server连接对象的示例代码:
using System.Data;
using System.Data.SqlClient;
using Dapper;
// 数据库连接字符串,实际使用时替换为自己的数据库地址和凭证
private static string connectionString = "Server=127.0.0.1;Database=TestDB;User Id=sa;Password=123456;";
// 获取数据库连接的方法
public static IDbConnection GetConnection()
{
return new SqlConnection(connectionString);
}
基础增删改查操作
查询操作
Dapper提供了Query方法用于执行查询SQL,返回的结果可以直接映射为对应的实体对象集合。首先定义一个和数据库表结构对应的实体类,然后执行查询。
假设数据库中有一张User表,结构如下:Id(int主键)、UserName(nvarchar)、Age(int)、CreateTime(datetime),对应的实体类定义:
public class User
{
public int Id { get; set; }
public string UserName { get; set; }
public int Age { get; set; }
public DateTime CreateTime { get; set; }
}
查询所有用户的示例代码:
public static List<User> GetAllUsers()
{
using (IDbConnection conn = GetConnection())
{
// 执行查询SQL,结果自动映射为User对象集合
string sql = "SELECT Id, UserName, Age, CreateTime FROM User";
return conn.Query<User>(sql).ToList();
}
}
插入操作
插入操作可以使用Execute方法,该方法返回受影响的行数。如果需要获取插入后生成的主键,可以配合SQL Server的SCOPE_IDENTITY()函数使用。
插入用户数据的示例代码:
public static int AddUser(User user)
{
using (IDbConnection conn = GetConnection())
{
string sql = "INSERT INTO User (UserName, Age, CreateTime) VALUES (@UserName, @Age, @CreateTime); SELECT CAST(SCOPE_IDENTITY() as int)";
// 传入实体对象作为参数,Dapper会自动匹配属性名和参数名
return conn.ExecuteScalar<int>(sql, user);
}
}
更新操作
更新操作和插入操作类似,使用Execute方法执行更新SQL即可。
更新用户年龄的示例代码:
public static int UpdateUserAge(int userId, int newAge)
{
using (IDbConnection conn = GetConnection())
{
string sql = "UPDATE User SET Age = @NewAge WHERE Id = @UserId";
// 使用匿名对象传递参数
return conn.Execute(sql, new { UserId = userId, NewAge = newAge });
}
}
删除操作
删除操作同样使用Execute方法,返回受影响的行数。
删除指定用户的示例代码:
public static int DeleteUser(int userId)
{
using (IDbConnection conn = GetConnection())
{
string sql = "DELETE FROM User WHERE Id = @UserId";
return conn.Execute(sql, new { UserId = userId });
}
}
参数化查询注意事项
Dapper默认支持参数化查询,上面的示例中通过匿名对象或者实体对象传递参数的方式都是参数化的,可以有效避免SQL注入问题。不要直接拼接SQL字符串传递参数,否则会有安全风险。
错误示例(不要这样写):
// 错误写法,存在SQL注入风险 string sql = "SELECT * FROM User WHERE UserName = '" + userName + "'";
正确写法:
// 正确写法,使用参数化查询
string sql = "SELECT * FROM User WHERE UserName = @UserName";
var user = conn.QueryFirstOrDefault<User>(sql, new { UserName = userName });
复杂对象映射
如果查询的结果涉及多表关联,返回的结果需要映射到多个实体对象,可以使用Dapper的Query方法的重载,通过splitOn参数指定分割列,实现复杂对象的映射。
假设查询用户和对应的订单信息,用户实体和订单实体定义如下:
public class User
{
public int Id { get; set; }
public string UserName { get; set; }
public List<Order> Orders { get; set; }
}
public class Order
{
public int OrderId { get; set; }
public int UserId { get; set; }
public decimal Amount { get; set; }
}
多表关联查询映射的示例代码:
public static List<User> GetUserWithOrders()
{
using (IDbConnection conn = GetConnection())
{
string sql = @"SELECT u.Id, u.UserName, o.OrderId, o.UserId, o.Amount
FROM User u
LEFT JOIN Order o ON u.Id = o.UserId";
var userDict = new Dictionary<int, User>();
// splitOn指定分割列,这里用OrderId作为分割点,前面的列映射到User,后面的映射到Order
var result = conn.Query<User, Order, User>(sql, (user, order) =>
{
if (!userDict.TryGetValue(user.Id, out User currentUser))
{
currentUser = user;
currentUser.Orders = new List<Order>();
userDict.Add(currentUser.Id, currentUser);
}
if (order != null)
{
currentUser.Orders.Add(order);
}
return currentUser;
}, splitOn: "OrderId").Distinct().ToList();
return result;
}
}
DapperORMC#_database修改时间:2026-06-19 15:39:43