如何在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
,它想要做任何一个 (在确定0
是ID
而1
是VALUE
之后):
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试图不介意列顺序,并且在一般情况下 (列不是所有不同的类型),当没有匹配时,不清楚正确的方法应该是什么。
选项:
-
创建表单的自定义类型:
public class SomeType { // could also be a struct, immutable, whatever public int Id {get;set;} public decimal Value {get;set;} }
并使用
T
===SomeType
-
使用非genericsAPI并重新映射:
Query(query, new { transactionid = topic }).Select( row => Tuple.Create((int)row.ID, (decimal)row.VALUE ).Whatever(...);
-
将结果列命名为
item1
和item2
(是的!)