我有一些函数,其原型看起来像这样:
public void doThings(string sql, dynamic dParams);
它使用这些参数进行某种SQL查询。我没有写它,但我必须使用它。当我做这样的事情时它工作正常:
doThings("select * from SomeTable where myval1=@v1 and myval2=@v2",
new
{
v1 = new Dapper.DbString()
{
Value = "yay",
IsAnsi = true,
Length = 50
},
v2 = new Dapper.DbString()
{
Value = "really",
IsAnsi = true,
Length = 32
}
});
但是当我第一次将动态参数放入ExpandoObject时
dynamic dynParams = new ExpandoObject();
dynParams.v1 = new Dapper.DbString()
{
Value = "yay",
IsAnsi = true,
Length = 50
}
doThings("query here", dynParams);
然后查询不返回任何结果。我不想拨打doThings()
并将该new
阻止十次写入十个不同的情况,我可能要查询myval2
或myval3
等等。是否有一些特殊方式我应该通过ExpandoObject
,或者其他一些方式我应该这样做?
答案 0 :(得分:3)
默认情况下,Dapper不支持Expandos,但您可以将expando传递给Dictionary<string,object>
的构造函数,然后将其作为动态参数传递。
答案 1 :(得分:1)
当你写下来时,看起来doThings
正在使用反射来获取所需的值:
new {
v1 = 1,
v2 = "foo"
}
您正在创建包含两个属性v1
和v2
的类型,但是当您这样做时
使用ExpandoObject
你的不会向ExpandoObject
添加任何新属性(它的所有神奇行为都是编译器生成的东西)。
如果你想在编译时使用已知属性的doThing
,我知道没有
问题。在运行时知道属性时,我能想到的唯一方法是使用Reflection.Emit
在运行时生成所需的匿名类型。查看this文章。
答案 2 :(得分:1)
正如@Michael B所提到的,Dapper不支持Expandos作为参数。
如果您需要动态构建参数,
根据此article,您可以使用DynamicParameters
。
因此,您可以构建从dynParams
到DynamicParameters
的翻译器,它看起来像:
dynamic dynParams = new ExpandoObject();
dynParams.v1 = new Dapper.DbString()
{
Value = "yay",
IsAnsi = true,
Length = 50
};
var parameters = new Dapper.DynamicParameters();
((ExpandoObject)dynParams).ToList().ForEach(kvp => parameters.Add(kvp.Key, kvp.Value));
它认为这可能是一个很好的功能。