Querying abstract types
Nobody has claimed this yet.
- Dominant language
- C#
- Stars
- 18.4k
- Forks
- 3.7k
- Avg merge
- 5h 8m
- Merged PRs (30d)
- 1
Description
[Table("Animal")]
public abstract class Animal
{
public int AnimalId { get; set; }
public string Discriminator { get { return GetType().Name; } }
}
[Table("Animal")]
public class Bird : Animal
{
public string FeatherColour { get; set; }
}
[Table("Animal")]
public class Dog : Animal
{
public string FurColour { get; set; }
}
var animals = Connection.Query<Animal>("SELECT * FROM Animal")
When doing the query above you get the exception Instances of abstract classes cannot be created. I would hope that this would return a list of animals with their values being their respective derived types.
In my case I'm using TPH inheritance so there's a field on the Animal table that specifies the derived type.
My attempts to add support for this have been unsuccessful. Before SqlMapper.cs::GetTypeDeserializer() is called if the type being passed in is an abstract class then I replace the type with the one returned in the following method:
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"]);
}
However it looks like at this point the reader hasn't been opened so it fails with Invalid attempt to read when no data is present.
Any recommendations on how to proceed? If there has been an effort to implement this elsewhere, please let me know!
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in SqlMapper.cs::GetTypeDeserializer() and review how the reader is accessed during Query. Compare that flow with the reported GetDerivedType attempt and the TPH Discriminator field. Done means querying the abstract Animal type can return instances of the appropriate derived types without the abstract-class exception.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- csharp, sql
- Domain
- backend, database
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 25/100