Search code examples
c#dapper

Dapper and Subclasses


I'm working with an existing EF data model that includes subclassed objects. That works fine when working with individual objects, but is quite slow when loading a large number of objects for analysis.

I started exploring Dapper as an alternative for populating POCO objects used for read-only analysis.

The trouble is, I can't see any means to correctly handle an object hierarchy.

If I have

class MyBase
{
}

class MyDerived1 : MyBase
{
}

class MyDerived2 : MyBase
{
}

Dapper correctly populates a list of MyBase

var mine = conn.Query<MyBase>("SELECT * from MyTable");

The Multimap capability doesn't seem to solve the problem (or am I missing something?).

Is there a way to solve this, short of making one round-trip to the database for each subclass?


Solution

  •  public class MyBase
        {
            public String BaseProp { get; set; }
        }
    
        public class MyDerived1 : MyBase
        {
            public String Derived1Prop { get; set; }
        }
    
        public class MyDerived2 : MyBase
        {
            public String Derived2Prop { get; set; }
        }
    

    Multimapping or a dynamic mapping should do the trick.

    MM:

    String query = "SELECT * FROM Table";
    
    var res = conn.Query<MyBase, MyDerived1, MyDerived2, Tuple<MyBase, MyDerived1, MyDerived2>>(query, (b, d1, d2) => Tuple.Create(b, d1, d2), splitOn: "Derived1Id,Derived2Id");
    

    enter image description here

    The dynamic mapping is also very cool and probably more flexible in your case (Thanks @Sam!)

    var res = conn.Query<dynamic>(query).Select(x => new Tuple<MyBase, MyDerived1, MyDerived2>(new MyBase() { BaseProp = x.BaseProp },
                                                                                                               new MyDerived1() { Derived1Prop = x.Derived1Prop },
                                                                                                               new MyDerived2() { Derived2Prop = x.Derived2Prop }));