例如,如果我有一个键/值对的列表,我可以根据该列表的内容声明一个匿名类型?我正在使用的具体情况是将参数传递给Dapper,我不知道我将会有多少参数.
List<Tuple<string,string>> paramList = new List<Tuple<string,string>>() { new Tuple<string,string>("key1","value1"),new Tuple<string,string>("key2","value2") ... };
我想将此List(或等效的Map)转换成一个匿名类型,我可以将其作为查询参数传递给Dapper.所以理想情况下,如果定义为匿名类型,上面的列表将会如下所示:
new { key1=value1,key2=value2,... }
我在StackOverflow上看到几个问题,要求在宣布匿名类型(“extendo objects”)之后扩展匿名类型,或者在创建对象后声明任意字段,但是我不需要这样做…我只需要先前一次声明类型.我的怀疑是,它将需要一些花哨的反思,如果可能的话.
我的理解是,编译器在编译时定义了一个匿名类的类型,所以如果该类的字段在运行时不可用,那么我可能不幸运.实际上,我的用例实际上与使用“extendo对象”来定义任意字段的实际上没有什么不同.
或者,如果有人知道更好的方式将查询参数传递给Dapper(而不是声明匿名类),我也很乐意听到.
谢谢!
UPDATE
对不起,迟来回到这个!这些答案都是伟大的,我希望我能给大家点数.我最后使用jbtule的解决方案(由Sam Saffron编辑),将IDynamicParameters传递给Dapper,所以我觉得我不得不给他答案.其他答案也很好,回答了我提出的具体问题.我非常感谢大家的时间在这个!
解决方法
Query,Execute和QueryMultiple方法采用动态参数.这可以是匿名类型,具体类型或实现IDynamicParameters的对象.
public interface IDynamicParameters { void AddParameters(IDbCommand command,Identity identity); }
这个界面非常方便,在运行任何sql之前调用AddParameters.这不仅可以让您对发送到sql的参数进行丰富的控制.它允许您连接DB特定的DbParameters,因为您可以访问该命令(您可以将其转换为特定于db的一个).这允许支持表值参数等.
Dapper包含可以用于您的目的的DynamicParameters的此接口的实现.这允许您连接匿名参数包并添加特定值.
您可以使用方法AddDynamicParams附加匿名类型.
var p = new DynamicParameters(); p.AddDynamicParams(new{a = "1"}); p.AddDynamicParams(new{b = "2",c = "3"}); p.Add("d","4") var r = cnn.Query("select @a a,@b b,@c c,@d d",p); // r.a == 1,r.b == 2,r.c == 3,r.d == 4