Подтвердить что ты не робот

Могу ли я возвратить коллекцию нескольких производных типов из запроса Dapper

У меня есть структура класса, подобная этому:

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

public class DeviceA : Device
{
    //Specific Behaviour
}

public class DeviceB : Device
{
    //Specific Behaviour
}

Мне нужно получить список Устройств или одно устройство, которое создается как соответствующий производный тип (на основе значения типа в записи устройства в БД). То есть коллекция объектов Device должна содержать несколько объектов с разными типами, все из которых получены из Device.

Я реализовал это следующим образом, но что-то просто не нравится.

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;
            });
    }
}

Правильно ли это достигается с помощью Dapper, или есть лучший подход?

4b9b3361

Ответ 1

В текущей сборке это, вероятно, единственный вариант (тем более, что базовый тип является абстрактным). Однако было бы неразумно думать о способах предлагать дискриминационную систему наследования. Это не то, что мы делали до сих пор просто потому, что оно не пришло - но это не кажется невозможным. Самая большая проблема, которую я вижу (кроме IL-споров, очевидно) - это просто то, как мы выражаем отношения.

Ответ 2

Я придумал это решение:

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;
                });       

Звучит сложно, но он работает!

Надеюсь, это может вам помочь.           }