Ingweland February 2016

How to access child tables with Entity Framework

I have following tables: Animal and ConcreteAnimal. I am going database first approach if it makes any difference in this example. Suppose they are separate entities. Then I have 2 DBSet(s) generated, and can update separately either of the table. Things change once I set ConcreteAnimal as child of Animal in entity designer. Entity Set field of ConcreteAnimal in entity designer becomes disabled and is automatically populated with the value of entity set of its parent class Animal. DBSet for ConcreteAnimal is not longer generated in the context. This means that I can no longer access the second, child, table. How am I supposed to add ConcreteAnimals to the database? Is it expected behavior? If yes, what is the logic behind it?

EDIT: OK, I tried following code and it works.

using(var context = new MyEntities())
{
    var concreteAnimal = new ConcreteAnimal
        {
            //setting properties here
            //both for Animal and specific to ConcreteAnimal
        };
    context.Animals.Add(concreteAnimal);
    context.SaveChanges();
}

Magic happened, and both tables were populated with correct data. This is good. However, it just does not look logical to me why we have DBSet for base class only?

Answers


Jonathan Magnan February 2016

You are currently using TPT Inheritance.

Common information are saved in the Animal table and specific information from a type in their own table.

You will find information you are looking in these articles:

Edit

Why we have DBSet for base class only

It's actually a good question, I cannot give an exact answer but from my opinion this is not implemented by default because it's not necessary and would be very confusing.

Just imagine some very complex TPT scenario with a lot of inheritance, they would have one DbSet for every concrete class (which could be easily hundred of additional DbSet), then now you will have to ask to yourself, from which DbSet to do you have to retrieve, add or remove this concrete type.

You can easily add the code yourself once it's generated (in a partial class) and it's will work.

public DbSet<ConcreteAnimal> ConcreteAnimals { get; set; }

Post Status

Asked in February 2016
Viewed 2,626 times
Voted 7
Answered 1 times

Search




Leave an answer