使用Dapper与Heidi存储过程查询MariaDB返回Null值求助
问题分析与解决方案
你的问题出在存储过程逻辑与Dapper调用方式不匹配,同时存在变量名冲突,导致查询无有效结果,最终Dapper返回Null。
核心问题点
- 变量名冲突:存储过程输入参数
folio与表列名Folio同名,MariaDB会将查询条件WHERE Folio = folio中的folio解析为列名而非参数,导致查询条件失效,返回空结果集。 - 输出参数与结果集重复定义:你既定义了OUT参数,又通过SELECT返回结果集,Dapper无法同时处理两种返回形式,导致映射逻辑混乱。
解决方案(两种可选)
方案1:用结果集返回(推荐,符合Dapper常规用法)
直接通过存储过程返回查询结果,让Dapper自动映射到PorHoraModel,无需OUT参数。
修改存储过程
CREATE DEFINER=`root`@`localhost` PROCEDURE `spPorHoraFolio_Get`( IN `p_folio` VARCHAR(14) -- 改名避免与列名冲突 ) LANGUAGE SQL NOT DETERMINISTIC CONTAINS SQL SQL SECURITY DEFINER BEGIN SELECT Folio, Estatus, HoraEntrada FROM listadoporhora WHERE Folio = p_folio; -- 使用改名后的参数 END
修改C#代码
public static PorHoraModel GetFolio(PorHoraModel modelo) { var builder = MariaDBConnector(); using (var connection = new MySqlConnection(builder)) { connection.Open(); var p = new DynamicParameters(); p.Add("@p_folio", modelo.Folio, DbType.String, ParameterDirection.Input); // 直接从结果集映射模型 var result = connection.QueryFirstOrDefault<PorHoraModel>( "spPorHoraFolio_Get", p, commandType: CommandType.StoredProcedure ); // 无匹配结果时返回原模型或null,按需调整 return result ?? modelo; } // using块自动释放连接,无需手动Close() }
方案2:用OUT参数返回值
若坚持使用OUT参数,需修改存储过程将查询结果赋值给OUT参数,再通过Dapper读取参数值。
修改存储过程
CREATE DEFINER=`root`@`localhost` PROCEDURE `spPorHoraFolio_Get`( IN `p_folio` VARCHAR(14), OUT `estatus` VARCHAR(5), OUT `horaEntrada` DATETIME ) LANGUAGE SQL NOT DETERMINISTIC CONTAINS SQL SQL SECURITY DEFINER BEGIN -- 将查询结果赋值给OUT参数 SELECT Estatus, HoraEntrada INTO estatus, horaEntrada FROM listadoporhora WHERE Folio = p_folio; END
修改C#代码
public static PorHoraModel GetFolio(PorHoraModel modelo) { var builder = MariaDBConnector(); using (var connection = new MySqlConnection(builder)) { connection.Open(); var p = new DynamicParameters(); p.Add("@p_folio", modelo.Folio, DbType.String, ParameterDirection.Input); // 输出参数需指定大小避免截断(对应存储过程的VARCHAR(5)) p.Add("@estatus", DbType.String, ParameterDirection.Output, size:5); p.Add("@horaEntrada", DbType.DateTime, ParameterDirection.Output); // 用Execute执行存储过程(无结果集返回) connection.Execute( "spPorHoraFolio_Get", p, commandType: CommandType.StoredProcedure ); // 从参数中取值赋值给模型 modelo.Status = p.Get<string>("@estatus"); modelo.HoraEntrada = p.Get<DateTime>("@horaEntrada"); return modelo; } }
额外注意事项
- 确保
PorHoraModel的属性名与数据库列名匹配,若不匹配可使用Dapper的[Column]特性映射,例如:[Column("Estatus")] public string Status { get; set; } using块会自动管理数据库连接,无需手动调用connection.Close()。
内容的提问来源于stack exchange,提问作者vmroche
相关产品推荐
相关产品推荐

