I have the following types:
public abstract class Vehicle {
public int Id { get; set; }
public double TopSpeed { get; set; }
}
public class Car : Vehicle {
public int Doors { get; set; }
}
public class Motorcycle : Vehicle {
public string Color { get; set; }
}
And I have a code-first DBContext:
public MyDbContext: DbContext {
public DbSet<Car> Cars { get; set; }
public DbSet<Motorcycle> Motorcycles { get; set; }
}
This works great if I query for a car or moto directly…
var dbContext = new MyDbContext();
var cars = dbContext.Set<Car>().Where(x=> x.TopSpeed>10); // <-- THIS WORKS
But if I want a list of all vehicles, whether car or moto, I would like to do this:
var dbContext = new MyDbContext();
var vehicles = dbContext.Set<Vehicle>().Where(x=> x.TopSpeed>10); // <-- THIS DOES NOT WORK
When I try the above code, I get an exception:
System.InvalidOperationException : The entity type Vehicle is not part
of the model for the current context.
That makes perfect sense… I didn’t add Vehicle to the context. I added car and moto. At this point, I’m not sure what to do. I tried adding Vehicle to my context, but that combined the tables for car and moto into one Vehicle table. I definitely want a separate table for cars and motos (and possibly a table for the vehicle base properties as well). What’s the best way to do this?
Have a Vehicles Properties of type DBSet of
Vehiclein your MyDbContext class.Now you can access all vehicles with the criteria like this
Keep in mind that you should have a Key Property in your entity classes (
IDor{ClassName}ID). Otherwise it is going to give you a run time error! (Yes the code will compile.)EDIT : As per the comment
By Default Entity Framework will do a Table Per Hierarchy.All Data in the hierarchy is saved in a single table and it use the
Discriminatorcolumn to identify which record belongs to which subtype. So As the result you will have one Vehicle table with columns same as properties of All your classes in the hierarchy with an extra column called “Discriminator“. For a Record for Car, It will have the “Car” value inside the Discriminator column.If you want to create Single table per each type, We will go for Table Per Type. Entity Framework will create a Table for the base class and seperate table for all child classes.
To make this happen, You can use Fluent API to override the configuration.
And the output is
Now You should be able to query Your Vehicle Entries like this
And the result is here
Notice that the result contains both
MotorCycletype andCartype.Check this link to decide what Inheritance Strategy to use.