Dapper作为C#生态中备受推崇的轻量级对象关系映射框架,以其卓越的性能和极简的API设计著称。与传统的重量级ORM相比,它不需要繁琐的配置即可快速实现应用程序与数据库的交互。通过扩展ADO.NET的接口,Dapper大幅减少了数据访问层的重复代码编写工作,同时保留了几乎等同于原生SQL的执行效率,成为众多开发者在处理数据库操作时的首选工具。

环境配置与数据库连接构建
在开始使用Dapper之前,首要任务是在项目中引入相关的依赖包。对于基于.NET Core或更高版本的项目,可以通过NuGet包管理器进行安装,或者直接在项目配置文件中添加相应的包引用。这种依赖管理方式能够确保项目始终使用稳定且兼容的版本,为后续的数据访问操作奠定坚实的基础。
以下是.NET项目中添加Dapper依赖的标准配置示例:
<PackageReference Include="Dapper" Version="2.1.35" />
Dapper本身并不负责管理数据库连接池,而是作为ADO.NET的扩展方法存在。因此,开发者需要手动配置数据库连接字符串,并编写相应的方法来实例化数据库连接对象。连接字符串中包含了服务器地址、数据库名称以及身份验证凭证等关键信息,确保应用程序能够安全地定位并访问目标数据库。
在获取连接对象时,必须确保在使用完毕后正确释放资源。利用C#的using语句块可以自动管理连接的生命周期,避免连接泄漏导致的数据库性能问题。以下代码展示了如何配置连接字符串并封装获取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提供了丰富的扩展方法来简化增删改查流程。对于查询操作,开发者只需定义与数据库表结构相对应的实体类,Dapper便会利用反射机制将查询结果自动映射为实体对象集合。这种机制极大地简化了数据读取的代码逻辑,使得开发者能够专注于业务层面的数据处理。
假设数据库中存在一张User表,包含Id、UserName、Age和CreateTime字段,对应的实体类与查询操作实现如下:
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())
{
string sql = "SELECT Id, UserName, Age, CreateTime FROM User";
return conn.Query<User>(sql).ToList();
}
}
除了查询,数据的插入、更新和删除同样依赖于Dapper提供的方法。插入数据时,若需要获取数据库自动生成的主键,可以结合数据库特定的函数来实现。而在执行更新和删除操作时,只需构建相应的SQL语句并传入受影响的条件参数即可。这些操作均通过执行SQL命令并返回受影响的行数来反馈执行结果。
// 插入用户并获取自增主键
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)";
return conn.ExecuteScalar<int>(sql, user);
}
}
// 更新用户年龄
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 });
}
}
// 删除指定用户
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 });
}
}
在进行上述所有数据操作时,必须严格遵循参数化查询的原则。直接拼接字符串来构建SQL语句不仅会导致代码可读性下降,更会引入严重的SQL注入安全漏洞。Dapper默认支持参数化查询,通过匿名对象或实体对象传递参数,能够确保用户输入被安全地处理为数据值而非可执行的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;
}
}
通过上述对Dapper环境配置、基础操作以及高级映射特性的详细解析,可以看出该框架在保持轻量级的同时,提供了极其灵活且强大的数据访问能力。掌握这些核心知识点,能够帮助开发者在C#项目中构建出高效、安全且易于维护的数据访问层。建议在后续的学习与实践中,进一步探索Dapper在事务处理、异步操作以及存储过程调用等方面的应用,以全面提升数据库编程的综合技能。
DapperORMC#_database修改时间:2026-06-19 15:39:43