Puis-je retourner une collection de plusieurs types dérivés à partir de la requête Dapper

c# dapper inheritance subclass

Question

J'ai une structure de classe similaire à celle-ci:

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

public class DeviceA : Device
{
    //Specific Behaviour
}

public class DeviceB : Device
{
    //Specific Behaviour
}

Je dois récupérer une liste de périphériques ou un seul périphérique instancié en tant que type dérivé approprié (basé sur une valeur de type dans l'enregistrement de périphérique dans la base de données). En d'autres termes, la collection d'objets Device doit contenir un certain nombre d'objets de types différents, tous dérivés de Device .

Je l'ai implémenté de la manière suivante, mais quelque chose ne me semble pas correct.

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

Est-ce la bonne façon d'y parvenir en utilisant Dapper ou y a-t-il une meilleure approche?

Réponse acceptée

Dans la version actuelle, c'est probablement la seule option (d'autant plus que le type de base est abstrait). Cependant, il ne serait pas déraisonnable de penser à des moyens de suggérer un système d'héritage discriminé. Ce n'est pas quelque chose que nous avons fait jusqu'ici simplement parce qu'il n'est pas arrivé - mais cela ne semble pas impossible. Le plus gros problème que je puisse voir (à part les querelles IL, évidemment) est simplement la façon dont nous exprimons la relation.


Réponse populaire

Je suis venu avec cette 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;
                });       

Cela semble compliqué, mais ça marche!

Espérons que cela peut vous aider. }



Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi
Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi