C# Dapper使用方法 C#如何用Dapper查询数据库

5次阅读

Dapper最简查询用IDbConnection.Query一行获取强类型列表,需确保连接已打开且传入IDbConnection实例;字段名与属性名大小写不敏感匹配;参数用匿名对象sql注入;单行用QueryFirstOrDefault,单值用QuerySingle;多结果集用QueryMultiple并顺序Read;动态结果支持dynamic或IDictionary;异步必须用QueryAsync等对应方法并await。

C# Dapper使用方法 C#如何用Dapper查询数据库

直接用 IDbConnection.Query 最简单

只要数据库连接打开,就能一行代码查出强类型列表。不需要写 SqlCommandSqlDataReader 或手动映射字段。

常见错误是忘了开连接,或者传了没实现 IDbConnection 的对象(比如直接传 String 连接字符串)。

  • Query 要求返回列名和 User 类的属性名完全匹配(大小写不敏感),否则字段为 NULL 或默认值
  • 参数用匿名对象传,Dapper 自动转成 SQL 参数,防止 SQL 注入:new { id = 123 }
  • 如果只查单行,用 QueryFirstOrDefault;查单个值(如 count(*)),用 QuerySingle
using (var conn = new SqlConnection(connectionString)) {     conn.Open();     var users = conn.Query("select * FROM Users WHERE Status = @status",                                      new { status = "Active" }); }

QueryMultiple 一次执行多个查询

适合主从表、关联数据需要分步处理的场景,比多次 Query 更省网络往返和连接开销。

容易忽略的是必须按顺序读取结果集——先 Read(),再 Read(),跳过或乱序会抛 InvalidOperationException

  • 每个 GridReader.Read() 返回一个 IEnumerable,不是单个对象
  • 不能用 QueryMultiple 做跨表 JOIN 后映射到多个类——它不支持自动分割字段,得靠 SQL 的 SELECT ... AS 显式别名 + 多个 Read
  • 记得调用 GridReader.Dispose()(用 using 最安全)
using (var conn = new SqlConnection(connectionString)) {     conn.Open();     using (var multi = conn.QueryMultiple("SELECT * FROM Orders; SELECT * FROM OrderItems;"))     {         var orders = multi.Read().ToList();         var items = multi.Read().ToList();     } }

动态结果用 QueryIDictionary

当表结构不确定、SQL 是拼出来的、或只想快速验证查询逻辑时,避免定义临时类。

注意 dynamic 在运行时解析属性,ide 没智能提示;而 IDictionary 更明确,且可直接遍历键值对

  • Query 返回的是 ExpandoObject,字段访问写法是 row.Name,但拼错名不会编译报错
  • Query> 返回每行一个字典,用 row["Name"] 取值,空值处理更可控
  • 两者都不支持 linq to Objects 的复杂操作(如嵌套 Select),建议尽早转成实体类
var rows = conn.Query>(     "SELECT TOP 5 Name, CreatedAt FROM Users ORDER BY Id"); foreach (var row in rows) {     Console.WriteLine($"{row["Name"]} - {row["CreatedAt"]}"); }

异步查询必须用 QueryAsync 系列方法

别在 async 方法里混用同步的 Query,会阻塞线程池线程,尤其在 Web API 高并发下容易拖垮吞吐量。

典型坑是忘了 await,或用了 .Result 强制同步等待,导致死锁(尤其 ASP.net Core 旧版本或 ui 线程上下文)。

  • 对应同步方法名加 Async 后缀:QueryAsyncExecuteAsyncQueryMultipleAsync
  • 连接对象本身不用特别配置,但确保数据库驱动支持异步(如 microsoft.Data.SqlClient,不是已淘汰的 System.Data.SqlClient
  • 异步方法返回 Task>,必须 await,不要用 GetAwaiter().GetResult()
public async Task> GetActiveUsersAsync(string connStr) {     using var conn = new SqlConnection(connStr);     await conn.Openasync();     return (await conn.QueryAsync(         "SELECT * FROM Users WHERE Status = @status",          new { status = "Active" })).AsList(); }

Dapper 的核心就三件事:开连接、写 SQL、选对 Query 方法。最常出问题的地方不在语法,而在连接生命周期管理、字段名匹配规则、以及异步/同步混用——这些地方一旦疏忽,错误往往不直接报在 Dapper 上,而是表现为超时、空数据、或线程卡死。

text=ZqhQzanResources