使用ExpandoObject传递动态参数

idl*_*age 5 c# sql dynamic parameter-passing expandoobject

我有一些函数,其原型看起来像这样: 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
            }
        });
Run Code Online (Sandbox Code Playgroud)

但是当我第一次将动态参数放入ExpandoObject时:

dynamic dynParams = new ExpandoObject();
dynParams.v1 = new Dapper.DbString()
    {
        Value = "yay",
        IsAnsi = true,
        Length = 50
    }
doThings("query here", dynParams);  
Run Code Online (Sandbox Code Playgroud)

然后查询不返回任何结果.我不想打电话doThings()和写new块十倍十个不同的场景,我可能要查询myval2myval3等等.是否有一些特殊方式我应该通过ExpandoObject,或者其他一些方式我应该这样做一般?

Mic*_*l B 5

Dapper 默认不支持 Expandos,但您可以将 expando 传递给 a 的构造函数,Dictionary<string,object>然后将其作为动态参数传递。


csh*_*olk 1

当您编写以下内容时,看起来像是doThings使用反射来获取所需的值:

new { 
    v1 = 1,
    v2 = "foo"
}
Run Code Online (Sandbox Code Playgroud)

您正在创建具有两个属性v1和的类型v2,但是当您使用时,ExpandoObject不会添加任何新属性ExpandoObject(它的所有神奇行为都是编译器生成的东西)。

如果你想使用doThing编译时已知的属性,我理解没有问题。当属性在运行时已知时,我能想到的唯一方法是使用Reflection.Emit. 看看这篇文章。