Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I return a collection of multiple Derived Types from Dapper query

I have a class structure similar to this:

public abstract class Device
{
    public int DeviceId { get; set; }
    //Additional Properties
}

public class DeviceA : Device
{
    //Specific Behaviour
}

public class DeviceB : Device
{
    //Specific Behaviour
}

I need to retrieve a list of Devices, or a single Device which is instantiated as the appropriate derived type (based upon a Type value in the Device Record in the DB). That is, the collection of Device objects should contain a number of objects with different Types, all of which are derived from Device.

I have implemented this the following way, but something just doesn't feel right about it.

public static IEnumerable<Device> AllDevices()
{
    using (var connection = CreateConnection())
    {
        connection.Open();
        return connection.Query<dynamic>("SELECT * FROM Device").Select<dynamic, Device>(d =>
            {
                Device device = null;
                if (d.DeviceTypeID == 1)
                    device = new DeviceA();
                else if (d.DeviceTypeID == 2)
                    device = new DeviceB();
                else throw new Exception("Unknown Device");
                device.DeviceId = d.DeviceID;
                return device;
            });
    }
}

Is this the correct way to achieve this using Dapper, or is there a better approach?

like image 468
GaryJL Avatar asked Apr 19 '13 15:04

GaryJL


People also ask

What is splitOn in dapper?

splitOn: CustomerId will result in a null customer name. If you specify CustomerId,CustomerName as split points, dapper assumes you are trying to split up the result set into 3 objects. First starts at the beginning, second starts at CustomerId , third at CustomerName .

How does Dapper mapping work?

Dapper maps data to the first type in the same way as it does if only one generic parameter has been supplied to the QueryAsync<T> method. If is then told to map data to the Category type, and to assign the resulting object to the product's Category property.


1 Answers

In the current build that is probably the only option (especially since the base-type is abstract). However, it wouldn't be unreasonable to think of ways of suggesting a discriminated inheritance system. It isn't something we've done so far simply because it hasn't come up - but it doesn't sound impossible. The biggest problem I can see (other than IL-wrangling, obviously) is simply how we express the relationship.

like image 54
Marc Gravell Avatar answered Oct 22 '22 02:10

Marc Gravell