Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Entity inheritance restrictions doesn't allow polymorphism through JSON #6001

Closed
soycabanillas opened this issue Jul 6, 2016 · 2 comments
Closed
Labels
closed-out-of-scope This is not something that will be fixed/implemented and the issue is closed.

Comments

@soycabanillas
Copy link

I tried to use inheritance to have different representations of the same data using a text/JSON field (oversimplified version):

public class Person
{
    [Key]
    public long Id { get; set; }

    [Required]
    public string FullName { get; set; }

    [Required]
    public string Serialized { get; set; }
}

public class Customer : Person
{
    public class CustomerData
    {
        public string VipLevel { get; set; }
        public string Preferences { get; set; }
    }

    [NotMapped]
    public CustomerData Data
    {
        get { return JsonConvert.DeserializeObject<CustomerData>(Serialized); }
        set { Serialized = JsonConvert.SerializeObject(value); }
    }
}

public class Employee : Person
{
    public class EmployeeData
    {
        public string Name { get; set; }
        public decimal Salary { get; set; }
    }

    [NotMapped]
    public EmployeeData Data
    {
        get { return JsonConvert.DeserializeObject<EmployeeData>(Serialized); }
        set { Serialized = JsonConvert.SerializeObject(value); }
    }
}

The context only has the Person entity:

    public DbSet<Person> Person{ get; set; }

When I try to add a Custormer or an Employee to the DbSet and call:

Context.SaveChanges();

The exception is thrown:

Exception message: The entity type 'Custormer' was not found. Ensure that the entity type has been added to the model.

To solve this, I tried to use TPH:

    public DbSet<Customer> Customer{ get; set; }
    public DbSet<Employee> Employee{ get; set; }

That forced me to use a "Discriminator" field, a new DbSet for every child (Customer and Employee) and a new repository for every child (Customer and Employee).
What is worse, I couldn't search for the parent entity anymore.

What if I need to query for any person, customer or employee, with a given name? Do I need to query twice the database?

@soycabanillas
Copy link
Author

soycabanillas commented Jul 7, 2016

Overloading some methods like:

DbSet<Entity>.Add()
DbSet<Entity>.Add<T>()

Could help to specify the type.

@rowanmiller
Copy link
Contributor

We've discussed this at length and concluded that we want to keep the current restrictions where the exact type of the entity being saved needs to be part of the model. Not doing this would make it very easy to think you have inheritance setup, but to inadvertently be just saving the base type data. Also, saving a derived type (Customer in your example) and then querying it back would result in a different type in the result of the query (Person in your example), since there would be no discriminator in the database.

The workaround for your scenario would be to have the ability to get a Person from a Customer (somewhat like a Clone() method).

@rowanmiller rowanmiller added the closed-out-of-scope This is not something that will be fixed/implemented and the issue is closed. label Jul 15, 2016
@ajcvickers ajcvickers reopened this Oct 16, 2022
@ajcvickers ajcvickers closed this as not planned Won't fix, can't repro, duplicate, stale Oct 16, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
closed-out-of-scope This is not something that will be fixed/implemented and the issue is closed.
Projects
None yet
Development

No branches or pull requests

3 participants