Question

We are hopefully moving over to use Dapper to provide the object relation mapping to our business models.

Along with these data models, we often encounter custom fields (not known at runtime) which are created by users and appear as part of the returned result set:

Id
Title
c_MyCustomField1
c_MyCustomField2

Currently, all these fields are returned and handled with a reader. We like to move all this over to Dapper but struggling to work out how to mix the strongly typed object mixed with dynamic custom fields.

We see our options like this:

  1. Get every result from dapper as dynamic and do our own binding.
  2. Get Dapper to bind to the strongly typed model and make a separate call to attach the custom fields.
  3. Extend Dapper to get in the middle add our specific user case to bind both the known and dynamic fields.

1 seems counterproductive and we'll possibly take a performance hit which is why you'd introduce Dapper in the first place. 2 we really can't do as this would require a massive change to the data provider. 3 I know I don't belong in the source of Dapper.

I think the holy grail would be ending up with a model like this:

class Model
{
    int Id {get; set;}
    string Title {get; set;}
    IList<CustomField> CustomFields {get; set;}
}

class CustomField : dynamic
{
    string Name {get; set;}
    object Value {get; set;}
}

Is there any way this could be done using Dapper?

As always, any suggestions greatly appreciated.

Was it helpful?

Solution

That can't be modeled cleanly in dapper currently; you might be able to do something with the non-generic API and then applying the bindings manually. Or maybe just wrap a dynamic:

class Model {
    private dynamic obj;
    public int Id { get { return obj.Id; } set { obj.Id = value; } }
    public string Title { get { return obj.Title; } set { obj.Title = value; } }

    public object this[string key] {
        get { return ((IDictionary<string,object>)obj)[key]; }
        set { ((IDictionary<string,object>)obj)[key] = value; }
    }
}

You can get a dynamic / IDictionary<string,object> by using Query without specifying a generic parameter.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top