Могу ли я возвратить коллекцию нескольких производных типов из запроса 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, или есть лучший подход?
Ответы
Ответ 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;
});
Звучит сложно, но он работает!
Надеюсь, это может вам помочь. }