Is there any way to use Dapper's multimap with explicit funcs per type?

dapper micro-orm

Question

We're looking for the following functionality when using the multimap semantics for Dapper (Dapper-Dot-Net):

    SqlMapper.Configure.ForTypeUseFunc<T>(Func<dynamic,T> func);

    //example usage
       Func<object,Foo> fooFunc = (dynamic o) => 
    new Foo{ 
    Name = o.Name, 
    Status = (StatusTypes)o.StatusID
    };


    SqlMapper.Configure.ForTypeUseFunc<Foo>(fooFunc);

 cnn.Query<Foo,Bar,Foo>...

So when Dapper splits the IDataReader for the 'Foo' type it passes all of the values as dynamic to fooFunc and would consequently do the same for 'Bar'. The 'dynamic' object passed in would be representative of the split columns (and just like the regular multi-map may have duplicate column names).

How can we achieve this?

Background

We use Dapper extensively on some legacy databases, but because of a lot of old patterns are forced to use the dynamic output to map results to objects (differing column names, nested objects, etc.)

The reality is that, although we're writing out the manual mapping, any inconsistencies between the database (which is outside of our control) and our object is perfectly and explicitly defined in the Func. A database of 50 tables (which I would consider medium-sized) only takes a couple of hours to map out and represents a tiny fraction of time of any development...totally worth it.

That's the good part.

The part we're struggling with is that we're having a tough time getting good code reuse out of our funcs even though they behave perfectly when used. Ideally we'd have some way of using Dapper's multi-map but assign a per-type Func:

I've looked into ITypeMap and IMemberMap and they seem to be geared towards custom mapping on a per-field basis. We're really looking for a custom mapping on a per-type basis (and we'll handle the assignments).

I'm happy to try to build this into Dapper myself (and have contributed ever so slightly in the past) but would love some guidance.

Thanks!

UPDATE

I'm currently trying Query<dynamic,dynamic,Foo> but that isn't splitting properly. This could work for us if it did split properly. We could effectively plug each dynamic into our func and return our strongly typed objects:

Query<dynamic,dynamic,Tuple<Foo,Bar>>((d1,d2)=>Tuple.Create(fooFunc(d1),barFunc(d2)));

Popular Answer

Dapper is sneaky enough to allow you to split on multiple dynamic types. There are many behind-the-scenes implementations that we could use to achieve the desired goal. Below is one.

Query<dynamic,dynamic,Tuple<Foo,Bar>>((d1,d2)=>Tuple.Create(fooFunc(d1),barFunc(d2)));

That's great. Behind the scenes you can store the type/func in whatever makes sense (e.g. Dictionary.

The issue we're dealing with now is that the duplicate column names have numbers appended to them (e.g. AddressID, AddressID1) making 'SELECT *' statements not so useful.



Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Is this KB legal? Yes, learn why
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Is this KB legal? Yes, learn why