简体   繁体   English

我可以从Dapper查询返回多个派生类型的集合

[英]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). 我需要检索设备列表,或者单个设备,它被实例化为适当的派生类型(基于DB中设备记录中的类型值)。 That is, the collection of Device objects should contain a number of objects with different Types, all of which are derived from Device . 也就是说, Device对象的集合应该包含许多具有不同类型的对象,所有这些对象都是从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? 这是使用Dapper实现这一目标的正确方法,还是有更好的方法?

In the current build that is probably the only option (especially since the base-type is abstract). 在当前的构建中,这可能是唯一的选择(特别是因为base-type是抽象的)。 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. 我能看到的最大问题(显然除了IL争吵之外)就是我们如何表达这种关系。

I've came up with this solution: 我想出了这个解决方案:

using (IDbConnection db = new MySqlConnection(ConfigurationManager.ConnectionStrings["yourConnection"].ConnectionString))
        {
            return db.Query<dynamic, DeviceA, DeviceB, Device>(@"
                Select
                    Discriminator,
                    ...
                From Device", (d, da, db) =>
                {
                    if (p.Discriminator == "DeviceA")
                    {
                        return new DeviceA();
                    }
                    else if (p.Discriminator == "DeviceB")
                    {
                         return new DeviceB();
                    }
                    return d;
                });       

Sounds tricky, but it does work! 听起来很棘手,但确实有效!

Hope it can help you. 希望它可以帮到你。 } }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM