C#如何使用Dapper框架_C#轻量级ORM提高数据库执行效率【高效率】

落静同学_9462

落静同学_9462

2026-04-23

930人浏览

原创

Dapper 能显著提升数据库执行效率,但需手动管理连接、SQL 和映射;必须显式打开连接、严格匹配参数名、事务中所有操作均需传 transaction 参数,批量操作应使用数据库原生方案而非循环执行。

c#如何使用dapper框架_c#轻量级orm提高数据库执行效率【高效率】

直接说结论:Dapper 能显著提升数据库执行效率,但前提是别把它当“全自动ORM”用——它不管理连接、不生成 SQL、不跟踪对象,所有性能红利都来自你手动写的那条 SQL 和你控制的那一次映射。写错参数名、漏掉 connection.Open()、在事务里忘传 transaction 参数,它不会报错提示,只会静默失败或抛出底层异常。

Connection 必须显式打开,否则 Query/Execute 直接炸

Dapper 所有扩展方法(Query<t></t>、Execute、QueryMultiple)都只扩展 IDbConnection,不接管生命周期。常见错误:

  • 用 new SqlConnection(...) 后没调 .Open() 就直接 Query<user>()</user> → 报 InvalidOperationException: Connection is not open
  • 写 using var conn = new SqlConnection(...),但把 Query 写在 using 块外 → 连接已释放,运行时报 ObjectDisposedException
  • 从 EF Core 的 DbContext.Database.GetDbConnection() 拿连接,但没检查 conn.State == ConnectionState.Open → 可能已关闭,尤其跨作用域后

正确做法:始终在 using 块内完成全部操作,并显式 .Open()(即使连接字符串含 Pooling=true,首次仍需打开):

using var conn = new SqlConnection(connStr);
conn.Open(); // 别省
var users = conn.Query<user>("SELECT * FROM Users WHERE Id = @id", new { id = 123 });
</user>

参数必须严格匹配,大小写敏感且不能拼错

Dapper 不做参数校验,SQL 里写 @Name,匿名对象里却传 new { name = "x" },就会报 InvalidOperationException: The parameterized query expects parameter '@Name'。这不是 SQL Server 的错,是 Dapper 绑定失败。

  • SQL 中参数名(如 @UserId)和匿名对象属性名必须完全一致,包括大小写
  • 传 null 值时,Dapper 自动转为 DBNull.Value,无需手动处理
  • 避免用 IDictionary<string object></string> 传参——键名大小写易错,且无编译期检查
  • 哪怕值是固定字符串(如 "Active"),也必须参数化:WHERE Status = @status,而不是 "WHERE Status = 'Active'"

事务必须显式传参,Query 和 Execute 都不自动感知

SqlTransaction 对象创建后,Dapper 不会自动绑定到后续所有调用。如果你只对 Execute 传了 transaction: tx,但 Query 没传,那这条查询就在事务外执行,可能读到脏数据或破坏一致性。

C#
C#

"避开 C# 常见错误——空陷阱、异步陷阱、LINQ 陷阱及资源泄漏。"

下载
  • 所有 Dapper 调用(包括 Query)参与事务,必须显式加 transaction: tx 参数
  • 别依赖 conn.BeginTransaction() 后的“隐式上下文”,Dapper 完全不维护这个
  • 批量操作 + 校验场景(如导入后查总数)必须统一传同一个 tx,否则事务失效

示例:

using var tx = conn.BeginTransaction();
try
{
    conn.Execute("INSERT INTO Logs (...) VALUES (...)", logs, transaction: tx);
    var count = conn.QuerySingle<int>("SELECT COUNT(*) FROM Logs", transaction: tx);
    if (count != logs.Count) throw new InvalidOperationException("Import mismatch");
    tx.Commit();
}
catch
{
    tx.Rollback();
    throw;
}
</int>

批量更新不能靠循环 Execute,得推给数据库做

Execute 本质就是执行一条 SQL 命令。用 foreach 循环调 Execute("UPDATE ... WHERE Id = @id", item),等于发 N 次网络请求,性能极差,且事务开销大。

  • SQL Server 推荐用表值参数(TVP):建好 TYPE,C# 构造 DataTable,用 DynamicParameters 传入,SQL 写成 UPDATE t SET ... FROM t INNER JOIN @updates u ON ...
  • MySQL/PostgreSQL 用 INSERT ... ON DUPLICATE KEY UPDATE 或 UPSERT + VALUES ROW(), ROW()... 语法
  • 别拼接多条语句用分号隔开(如 "UPDATE...; UPDATE..."),多数驱动不支持,会报 Incorrect syntax near ';'

真正影响效率的从来不是 Dapper 本身,而是你让数据库干了多少活、网络往返了多少次。这点最容易被忽略——以为装了 Dapper 就万事大吉,结果慢还是慢。

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

c#

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
python是前端还是后端
python是前端还是后端

Python属于前端也属于后端,其灵活性和丰富的生态系统使得开发人员能够在不同的领域中灵活运用。本专题为大家提供python相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.11

2683

5

前端如何实现即时通讯
前端如何实现即时通讯

实现即时通讯的方法有WebSocket、Long Polling、Server-Sent Events、WebRTC等等。详细介绍:1、WebSocket,它可以在客户端和服务器之间建立持久连接,实现实时的双向通信,前端可以使用 WebSocket API来创建WebSocket连接,并通过发送和接收消息来实现即时通讯;2、Long Polling,是一种模拟实时通信的技术等等。

2023.10.09

5823

6

前端和后端的区别
前端和后端的区别

前端关注的是用户界面的设计和交互,而后端则注重数据处理和逻辑控制。想了解更多前端后端的相关内容,可以阅读本专题下面的文章。

2024.03.19

6790

13

php和前端的关联介绍
php和前端的关联介绍

php既可以作为前端语言,也可以作为后端语言。想了解更多php和前端的相关内容,可以阅读本专题下面的文章。

2024.03.22

6518

10

前端外包工作内容有哪些
前端外包工作内容有哪些

前端外包工作内容包括:1. 网站和应用程序开发;2. 用户界面和交互设计;3. 用户体验优化;4. 设计和视觉开发;5. 跨浏览器兼容性;6. 性能优化;7. 维护和更新;8. 项目管理和沟通。想了解更多前端的相关内容,可以阅读本专题下面的文章。

2024.05.22

923

5

c#是什么意思
c#是什么意思

C#是一种通用的面向对象编程语言,它在.NET框架上运行,可用于开发各种类型的应用程序。本专题为大家提供c#相关的各种文章、以及下载和课程。

2023.08.08

1052

5

什么是c#
什么是c#

C#(读作C Sharp)是一种现代的、通用的、面向对象的编程语言。它由微软公司开发,于2000年首次发布,主要用于开发Windows桌面应用程序、Web应用程序、移动应用程序以及游戏开发等领域。C#是一种类型安全和托管的编程语言,它结合了C++的强大性能和C语言的简单易学特点,并引入了许多新的特性和概念,如委托、属性、泛型和异步编程等,以提高开发效率和代码可维护性。

2023.08.31

3091

3

C#中base关键字的用法
C#中base关键字的用法

在C#中,base关键字用于访问当前类的基类成员,这包括基类的字段、属性、方法、构造函数、索引器以及事件。想了解更多C#的相关内容,可以阅读本专题下面的文章。

2024.03.13

905

8

C#Task用法
C#Task用法

Task在C#中是用于表示异步操作的对象,它位于System.Threading.Tasks命名空间中。想了解更多C#中各种用法的相关内容,可以阅读本专题下面的文章。

2024.03.14

2635

11

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C++ Core Guidelines
C++ Core Guidelines

共0课时 | 0人学习

C++ Reference
C++ Reference

共0课时 | 0人学习

C++ 官方标准说明
C++ 官方标准说明

共0课时 | 0人学习