使用Dapper+MySQL遇异常:初始可查数据,增删改后无法读取
问题排查与解决方案
让我帮你一步步拆解这个问题,从代码里的明显隐患到可能导致你遇到的“执行几次操作后无法读取数据”的核心原因:
1. 先修复最危险的SQL注入隐患(同时避免潜在语法问题)
你的代码直接把academyId拼接到SQL字符串里,这不仅是严重的安全漏洞(攻击者可以构造恶意值执行任意SQL),还可能因为参数格式问题引发隐性错误。
替换成Dapper支持的参数化查询,这是标准且安全的做法:
public List<AcademyTeamsEntity> GetAcademyTeams(int academyId) { using (IDbConnection db = new MySql.Data.MySqlClient.MySqlConnection(ClsConnectionString.connectionString)) { string query = @"SELECT * FROM academyteams where AcademyId = @AcademyId order by CategoryId asc "; return db.Query<AcademyTeamsEntity>(query, new { AcademyId = academyId }).ToList(); } }
参数化查询还能让数据库缓存查询计划,提升性能,一举多得。
2. 连接池耗尽:可能是你遇到的核心问题
你用using包裹连接的做法本身是对的,它会自动释放连接回连接池,但如果你的增删改操作代码没有正确释放连接,就会导致连接池里的可用连接被耗尽——这时候新的查询请求拿不到连接,就会表现为“无法读取记录/无法通信”,但表面上连接还能建立。
排查点:
- 检查所有增删改操作的代码,确保它们也用
using包裹IDbConnection,或者手动调用Close()/Dispose()释放连接; - 查看你的连接字符串配置,是否设置了合理的
Max Pool Size(默认是100),如果并发操作较多,可以适当调大这个值(比如Max Pool Size=200),但优先确保所有连接都被正确释放。
3. 事务未提交导致的读取异常
如果你的保存/更新/删除操作使用了事务,但没有正确提交(比如遗漏了tran.Commit(),或者异常后没回滚),这些变更不会写入数据库。另外,某些事务隔离级别也会导致新连接无法读取未提交的变更。
检查你的事务代码,确保逻辑正确:
using (var db = new MySqlConnection(ClsConnectionString.connectionString)) { db.Open(); using (var tran = db.BeginTransaction()) { try { // 执行增删改逻辑 tran.Commit(); } catch { tran.Rollback(); throw; // 重新抛出异常,让上层处理 } } }
4. 添加异常捕获,定位具体错误
你的查询代码没有异常处理,无法知道到底是连接超时、SQL错误还是锁表问题。加上异常捕获,记录详细错误信息,能帮你快速定位问题:
public List<AcademyTeamsEntity> GetAcademyTeams(int academyId) { try { using (IDbConnection db = new MySql.Data.MySqlClient.MySqlConnection(ClsConnectionString.connectionString)) { string query = @"SELECT * FROM academyteams where AcademyId = @AcademyId order by CategoryId asc "; return db.Query<AcademyTeamsEntity>(query, new { AcademyId = academyId }).ToList(); } } catch (Exception ex) { // 这里可以写入日志系统,或者输出到控制台 Console.WriteLine($"查询AcademyTeams失败: {ex.Message}\n堆栈跟踪: {ex.StackTrace}"); throw; // 不要吞掉异常,让上层处理 } }
5. 其他快速排查方向
- 查看数据库慢查询日志,确认你的查询是否因为锁表或执行缓慢超时;
- 核对
AcademyTeamsEntity的属性与数据库列名的映射(Dapper默认大小写不敏感,但如果列名有下划线,比如category_id,实体属性是CategoryId,可以用[Column("category_id")]标注确保映射正确); - 临时重启应用和数据库,排除临时的连接池或数据库服务异常。
内容的提问来源于stack exchange,提问作者Ram Singh
相关产品推荐
相关产品推荐

