Sto utilizzando l'ereditarietà del database Tabella per gerarchia in cui le colonne per tutti i tipi derivati sono in una singola tabella. Ogni tabella derivata viene identificato utilizzando un campo Discriminatore stringa che contiene il nome della classe derivata:Interrogazione modelli astratti in dapper
---------------------
| tanimal |
---------------------
| animalid |
| discriminator |
| furcolour |
| feathercolour |
---------------------
public abstract class Animal
{
public int AnimalId { get; set; }
public string Discriminator { get { return GetType().Name; } }
}
public class Bird : Animal
{
public string FeatherColour { get; set; }
}
public class Dog : Animal
{
public string FurColour { get; set; }
}
Come previsto, durante il recupero di questo metodo di interrogazione tramite di Dapper riceverò Instances of abstract classes cannot be created
. Spero che questo restituisca un elenco di Animal con i loro valori come rispettivi tipi derivati.
var animals = Connection.Query<Animal>("SELECT * FROM tanimal")
I miei tentativi di aggiungere supporto per questo non sono riusciti. Prima SqlMapper.cs :: GetTypeDeserializer() viene chiamato se il tipo di essere passata in è una classe astratta poi sostituisco il tipo con quello restituito nel seguente metodo:
static Type GetDerivedType(Type abstractType, IDataReader reader)
{
var discriminator = abstractType.GetProperty("Discriminator");
if (discriminator == null)
throw new InvalidOperationException("Cannot create instance of abstract class " + abstractType.FullName + ". To allow dapper to map to a derived type, add a Discriminator field that stores the name of the derived type");
return Type.GetType((string)reader["Discriminator"]);
}
Tuttavia sembra che a questo punto il il lettore non è stato aperto, quindi fallisce con Invalid attempt to read when no data is present
.
È questo l'approccio corretto da prendere? C'è stato qualche sforzo per supportarlo altrove?
https: // GitHub. it/StackExchange/dapper-dot-net/issues/262 – ajbeaven