Dapper的QueryFirst和FirstOrDefault有什么区别 Dapper查询方法选择

QueryFirst要求必须有结果,否则抛InvalidOperationException异常;QueryFirstOrDefault查无结果时返回默认值,更安全。仅当100%确定数据存在时用QueryFirst,如主键查询;多数场景推荐QueryFirstOrDefault。

QueryFirst 和 QueryFirstOrDefault 的核心区别

两者都用于执行查询并返回单个结果,但对“查不到数据”这一情况的处理完全不同:

  • QueryFirst:要求数据库中必须至少有一行匹配结果。如果没查到,直接抛出 InvalidOperationException 异常。
  • QueryFirstOrDefault:允许查不到数据。此时不报错,而是返回对应类型的默认值——比如引用类型是 nullint0boolfalse

什么时候该用 QueryFirst

仅在你**100%确定某条记录必然存在**时才用它。典型场景包括:

  • 根据主键查询(如 SELECT * FROM Users WHERE Id = @id),且已确认该 ID 在库中一定有值;
  • 聚合查询后必有结果,比如 SELECT COUNT(*) FROM Orders 配合 QueryFirst
  • 业务逻辑强制约束下不可能为空的数据,例如系统配置表的默认项。

为什么多数时候推荐 QueryFirstOrDefault

现实开发中,绝大多数查询都无法提前保证数据一定存在。用 QueryFirst 容易因一条缺失数据导致整个接口崩溃。

  • 查用户信息时 ID 输错、被删除,用 First 会炸,用 FirstOrDefault 返回 null 后可友好提示“用户不存在”;
  • 关联查询中外键可能为空,或条件筛选后无匹配,用 FirstOrDefault 更安全;
  • 配合 if 判断更自然:var user = conn.QueryFirstOrDefault(...); if (user == null) { ... }

别和 Single 系列混淆

QueryFirst / FirstOrDefault 关注的是“取第一个”,不管后面还有没有其他行;而 QuerySingle / SingleOrDefault 要求结果**有且仅有一行**,多于一行也会报错。

  • 查邮箱唯一性验证?用 QuerySingleOrDefault,因为期望最多一个;
  • 查最新一条订单?用 QueryFirstOrDefault("SELECT TOP 1 ... ORDER BY Created DESC")
  • 查统计总数?用 QueryFirst("SELECT COUNT(...)") 更合适,因为 COUNT 永远返回一行。

基本上就这些。选哪个不是看名字顺口,而是看你的查询语义和容错需求。