具有条件 select 查询的存储过程中的 Dapper 转换问题

Dapper casting issue in stored procedure with conditional select queries

我在调用具有两个 select 查询的存储过程时遇到转换问题,其中只有一个查询将基于 if else 条件执行。 select 查询都具有相同的 selected 值,但顺序不同。只是提供一个想法,

IF (some condition)
 SELECT
  t1.Id,
  t1.Title,
  t1.Description
 FROM Table1 t1
ELSE
 SELECT
  t1.Title,
  t1.Id,
  t1.Description
 FROM Table1 t1

场景:

  1. 执行这个存储过程的方法被调用,条件满足。
  2. 返回预期数据。
  3. 调用了执行该存储过程的方法,条件不满足。
  4. 代码中抛出转换错误。

Error parsing column 0 (Id=123 - Int64)
System.InvalidCastException: Unable to cast object of type 'System.Int64' to type 'System.String'.
at Deserializec2c12182-6e8d-4a6e-8f54-e60138f070ee(IDataReader )

将它们更改为相同的 selection 顺序将绕过该问题,但有人可以判断这是 Dapper 的缓存问题还是其他问题吗?

感谢任何帮助。谢谢

Looking at the source code for Dapper,看来生成的映射代码使用索引从DbDataReader读取数据。我想按索引访问比按名称访问更快,这就是为什么这样做的原因。

This mapper is cached(为了性能)并用于相同命令文本的相同运行,因此 Dapper 希望列的顺序相同。

我个人认为这是一个错误,缓存逻辑在检查现有映射器时应考虑列顺序。 Feel free to file a bug report.


所述,解决方法是使用显式 CommandDefinition

关闭缓存
var cmdDef = new CommandDefinition("select ... blah ...", new { a, b }, commandType: CommandType.Text, flags: CommandFlags.NoCache);

这应该不是必需的,Dapper 应该在尝试重用之前检查 reader 是否相同。

第一条和第二条语句中的列顺序似乎不正确。因此,当 dapper 按列索引查询存储过程时,两个语句中的列类型不匹配。在第一条语句中,第一列的数据类型是 INT 64,而在第二条语句中,它是 String。因此问题。所以正确的 SQL 过程应该是这样的:

IF (some condition)
 SELECT
  t1.Id,
  t1.Title,
  t1.Description
 FROM Table1 t1
ELSE
 SELECT
  t1.Id,
  t1.Title,
  t1.Description
 FROM Table1 t1