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

后端 未结 3 514
隐瞒了意图╮
隐瞒了意图╮ 2021-02-01 22:56

Given an array of values, I would like to create an anonymous object with properties based on these values. The property names would be simply \"pN\" where N

相关标签:
3条回答
  • 2021-02-01 23:06

    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.

    0 讨论(0)
  • 2021-02-01 23:06

    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);
        }
    }
    
    0 讨论(0)
  • 2021-02-01 23:06

    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"
    
    0 讨论(0)
提交回复
热议问题