使用ExpandoObject传递动态参数

问题描述 投票:5回答:3

我有一些函数,其原型看起来像这样: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阻止了十次不同的情况,我可能想查询myval2myval3等等。有什么特别的方式我应该通过ExpandoObject,或者其他一些方式我应该这样做一般吗?

c# sql dynamic parameter-passing expandoobject
3个回答
3
投票

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


1
投票

当你写道时,看起来doThings正在使用反射来获得所需的值:

new { 
    v1 = 1,
    v2 = "foo"
}

你正在创建具有两个属性v1v2的类型,但是当你使用ExpandoObject时,你不会向ExpandoObject添加任何新属性(它的所有魔法行为都是编译器生成的东西)。

如果你想在编译时使用doThing属性,我知道没有问题。当在运行时知道属性时,我能想到的唯一方法是使用Reflection.Emit在运行时生成所需的匿名类型。看看this的文章。


1
投票

正如@Michael B所提到的,Dapper不支持Expandos作为params。

如果您需要动态构建参数集,根据此article,您可以使用DynamicParameters

因此,您可以构建一个从dynParamsDynamicParameters的翻译器,它看起来像:

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));

它认为这可能是一个很好的功能。

© www.soinside.com 2019 - 2024. All rights reserved.