如何在Dapper中使用generics和Nullable 类型进行实现?

我有这个电话:

public IObservable Subscribe(object topic, string service, string connectionString, string query) { try { this.connection.ConnectionString = connectionString; this.connection.Open(); this.connection.Query(query, new { transactionid = topic }).ToObservable().Subscribe(message => this.subject.OnNext(message)); return this.subject; } catch (Exception e) { this.subject.OnError(e); return this.subject; } finally { this.subject.OnCompleted(); this.connection.Close(); } } 

这是我的查询:

 with IDS as (select L1_ID, L2_ID, L1_VALUE, L2_VALUE from MYDB where MYDB.ID = :transactionid) select * from (select L1_ID as ID, round(L1_VALUE, 28) as VALUE from IDS union select L2_ID as ID, round(L2_VALUE, 28) as VALUE from IDS) UN 

抛出这个错误:

System.Tuple 2[[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.Nullable需要无参数默认构造函数或一个匹配签名(System.String ID,System.Decimal VALUE) 2[[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.Nullable 1 [[System.Decimal,mscorlib,Version = 4.0.0.0,Culture = neutral,PublicKeyToken = b77a5c561934e089]],mscorlib,Version = 4.0.0.0,Culture = neutral,PublicKeyToken = b77a5c561934e089]]具体化

这里的问题不是Nullable ,而是Tuple<,>

Dapper采用两种模式中的一种。 我们假设我们的数据有列

 ID varchar VALUE decimal 

(因为在你的场景中似乎就是这种情况)

要将它加载到T ,它想要做任何一个 (在确定0ID1VALUE之后):

 T row = new T() { ID = reader.GetInt32(0), VALUE = reader.GetDecimal(1) }; 

要么

 T row = new T(ID: reader.GetInt32(0), VALUE: reader.GetDecimal(1)); 

请注意,我在这里简化了很多东西,并且它对案例敏感性相当宽容,但这基本上是它想要的。

现在,问题是: Tuple 没有其中任何一个 。 它有构造函数:

 public Tuple(T1 item1, T2 item2); 

哪个在这里不起作用 – 小巧玲珑不能绝对肯定什么意思去哪里,所以它不会尝试 。 这听起来很苛刻,但是dapper试图不介意列顺序,并且在一般情况下 (列不是所有不同的类型),当没有匹配时,不清楚正确的方法应该是什么。

选项:

  1. 创建表单的自定义类型:

     public class SomeType { // could also be a struct, immutable, whatever public int Id {get;set;} public decimal Value {get;set;} } 

    并使用T === SomeType

  2. 使用非genericsAPI并重新映射:

     Query(query, new { transactionid = topic }).Select( row => Tuple.Create((int)row.ID, (decimal)row.VALUE ).Whatever(...); 
  3. 将结果列命名为item1item2 (是的!)