How to create an anonymous object with property names determined dynamically?

孤者浪人 提交于 2019-12-02 20:44:16
Sam Saffron

You are misusing Dapper, you should never need to do this, instead either implement IDynamicParameters or use the specific extremely flexible DynamicParameters class.

In particular:

string sql = "select * from Account where Id = @id and username = @name";
var values = new DynamicParameters();
values.Add("id", 1);
values.Add("name", "bob");
var accounts = SqlMapper.Query<Account>(connection, sql, values);

DynamicParameters can take in an anonymous class in the constructor. You can concat DynamicParameters using the AddDynamicParams method.

Further more, there is no strict dependency on anon-types. Dapper will allow for concrete types as params eg:

class Stuff
{
   public int Thing { get; set; }
}

...

cnn.Execute("select @Thing", new Stuff{Thing = 1});

Kevin had a similar question: Looking for a fast and easy way to coalesce all properties on a POCO - DynamicParameters works perfectly here as well without any need for magic hoop jumping.

Not exactly an anonymous object, but what about implementing a DynamicObject which returns values for p1 ... pn based on the values in the array? Would that work with Dapper?

Example:

using System;
using System.Dynamic;
using System.Text.RegularExpressions;

class DynamicParameter : DynamicObject {

    object[] _p;

    public DynamicParameter(params object[] p) {
        _p = p;
    }

    public override bool TryGetMember(GetMemberBinder binder, out object result) {
        Match m = Regex.Match(binder.Name, @"^p(\d+)$");
        if (m.Success) {
            int index = int.Parse(m.Groups[1].Value);
            if (index < _p.Length) {
                result = _p[index];
                return true;
            }
        }
        return base.TryGetMember(binder, out result);
    }

}

class Program {
    static void Main(string[] args) {
        dynamic d1 = new DynamicParameter(123, "test");
        Console.WriteLine(d1.p0);
        Console.WriteLine(d1.p1);
    }
}

You cannot dynamically create anonymous objects. But Dapper should work with dynamic object. For creating the dynamic objects in a nice way, you could use Clay. It enables you to write code like

var person = New.Person();
person["FirstName"] = "Louis";
// person.FirstName now returns "Louis"
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!