使用 ExpandoObject 传递动态参数
本文关键字:动态 参数 ExpandoObject 使用 | 更新日期: 2023-09-27 18:32:33
我有一些函数,其原型看起来像这样: 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
,或者我应该以其他
Dapper 默认不支持 Expandos,但您可以将 expando 传递给Dictionary<string,object>
的构造函数,然后将其作为动态参数传递。
正如@Michael B所提到的,Dapper不支持Expandos作为参数。
如果您需要动态构建参数集,根据本文,您可以使用 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));
它认为这可能是一个不错的功能。
当您编写以下内容时,看起来doThings
正在使用反射来获取所需的值:
new {
v1 = 1,
v2 = "foo"
}
您正在创建具有两个属性 v1
和 v2
的类型,但是当您使用 ExpandoObject
your 不会向ExpandoObject
添加任何新属性(它的所有魔术行为都是编译器生成的东西)。
如果您想将doThing
与编译时已知的属性一起使用,我知道没有问题。当属性在运行时已知时,我能想到的唯一方法是在运行时使用 Reflection.Emit
生成所需的匿名类型。看看这篇文章。