Dapper最简查询用IDbConnection.Query一行获取强类型列表,需确保连接已打开且传入IDbConnection实例;字段名与属性名大小写不敏感匹配;参数用匿名对象防SQL注入;单行用QueryFirstOrDefault,单值用QuerySingle;多结果集用QueryMultiple并顺序Read;动态结果支持dynamic或IDictionary;异步必须用QueryAsync等对应方法并await。
直接用
最简单
只要数据库连接打开,就能一行代码查出强类型列表。不需要写
、
或手动映射字段。
常见错误是忘了开连接,或者传了没实现
的对象(比如直接传
连接字符串)。
要求返回列名和
类的属性名完全匹配(大小写不敏感),否则字段为
或默认值
参数用匿名对象传,Dapper 自动转成 SQL 参数,防止 SQL 注入:
如果只查单行,用
;查单个值(如
),用
一次执行多个查询
适合主从表、关联数据需要分步处理的场景,比多次
更省网络往返和连接开销。
容易忽略的是必须按顺序读取结果集——先
,再
,跳过或乱序会抛
。
每个
返回一个
,不是单个对象
不能用
做跨表 JOIN 后映射到多个类——它不支持自动分割字段,得靠 SQL 的
显式别名 + 多个
记得调用
(用
最安全)
动态结果用
或
当表结构不确定、SQL 是拼出来的、或只想快速验证查询逻辑时,避免定义临时类。
C函数速查手册(CHM版)
C函数速查手册(CHM版)
下载
注意
在运行时解析属性,IDE 没智能提示;而
更明确,且可直接遍历
键值对
。
返回的是
,字段访问写法是
,但拼错名不会编译报错
返回每行一个字典,用
取值,空值处理更可控
两者都不支持 LINQ to Objects 的复杂操作(如嵌套
),建议尽早转成实体类
异步查询必须用
系列方法
别在
方法里混用同步的
,会阻塞线程池线程,尤其在 Web API 高并发下容易拖垮吞吐量。
典型坑是忘了
,或用了
强制同步等待,导致死锁(尤其 ASP.NET Core 旧版本或 UI 线程上下文)。
对应同步方法名加
后缀:
、
、
连接对象本身不用特别配置,但确保数据库驱动支持异步(如
,不是已淘汰的
)
异步方法返回
,必须
,不要用
Dapper 的核心就三件事:开连接、写 SQL、选对 Query 方法。最常出问题的地方不在语法,而在连接生命周期管理、字段名匹配规则、以及异步/同步混用——这些地方一旦疏忽,错误往往不直接报在 Dapper 上,而是表现为超时、空数据、或线程卡死。
IDbConnection.QuerySqlCommandSqlDataReaderIDbConnectionstringQueryUsernullnew { id = 123 }QueryFirstOrDefaultCOUNT(*)QuerySingleusing (var conn = new SqlConnection(connectionString))
{
conn.Open();
var users = conn.Query("SELECT * FROM Users WHERE Status = @status",
new { status = "Active" });
} QueryMultipleQueryRead() Read() InvalidOperationExceptionGridReader.Read() IEnumerableQueryMultipleSELECT ... ASReadGridReader.Dispose()usingusing (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();
}
} QueryIDictionarydynamicIDictionaryQueryExpandoObjectrow.NameQuery> row["Name"]Selectvar rows = conn.Query>(
"SELECT TOP 5 Name, CreatedAt FROM Users ORDER BY Id");
foreach (var row in rows)
{
Console.WriteLine($"{row["Name"]} - {row["CreatedAt"]}");
} QueryAsyncasyncQueryawait.ResultAsyncQueryAsyncExecuteAsyncQueryMultipleAsyncMicrosoft.Data.SqlClientSystem.Data.SqlClientTask> awaitGetAwaiter().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();
} 