I have a pretty straight forward set of database tables, like:
Vehicle
Id
RegNo
Car
Id (FK of Vehicle.Id)
OtherStuff
Bike
Id (FK of Vehicle.Id)
MoreStuff
My class model is as you'd expect: with Vehicle being an abstract class, and then Car and Bike being subclasses of it.
I have setup my EF4.1 Code First configuration as follows:
class VehicleConfiguration : EntityTypeConfiguration<Vehicle> {
public VehicleConfiguration() {
ToTable("Vehicles");
Property(x => x.Id);
Property(x => x.RegNo);
HasKey(x => x.Id);
}
}
class CarConfiguration : EntityTypeConfiguration<Car> {
public CarConfiguration() {
ToTable("Cars");
Property(x => x.OtherStuff);
}
}
class BikeConfiguration : EntityTypeConfiguration<Bike> {
public BikeConfiguration() {
ToTable("Bikes");
Property(x => x.MoreStuff);
}
}
However I am getting numerous strange exceptions when EF tried to build its model configuration.
Currently it is throwing out this:
System.Data.EntityCommandExecutionException: An error occurred while executing the command definition. See the inner exception for details. ---> System.Data.SqlClient.SqlException: Invalid column name 'Discriminator'.
Where is it getting that column name from? It's not in any of my code or the database itself. It must be some convention that's taking over control. How do I instruct EF to use table-per-type?
If I remove the "abstract" keyword from my Vehicle class (which I did as a sanity test somewhere along the line) then I get a different exception like the following:
(35,10) : error 3032: Problem in mapping fragments starting at lines 30, 35:EntityTypes AcmeCorp.Car, AcmeCorp.Bike are being mapped to the same rows in table Vehicles. Mapping conditions can be used to distinguish the rows that these types are mapped to.
I'm obviously doing something terribly wrong, but what? I've followed the MSDN docs and all the other TPT + EF4.1 articles I can find!
Inheritance with EF Code First: Table per Hierarchy (TPH)
Table-per-hierarchy and discriminator configuration. By default, EF maps the inheritance using the table-per-hierarchy (TPH) pattern. TPH uses a single table to store the data for all types in the hierarchy, and a discriminator column is used to identify which type each row represents.
The Entity Framework Core Fluent API HasDefaultValue method is used to specify the default value for a database column mapped to a property. The value must be a constant.
Have you read the following article?
It is a 3 part article covering the following approaches
Table per Hierarchy (TPH): Enable polymorphism by denormalizing the SQL schema, and utilize a type discriminator column that holds type information.
Table per Type (TPT): Represent "is a" (inheritance) relationships as "has a" (foreign key) relationships.
Table per Concrete class (TPC): Discard polymorphism and inheritance relationships completely from the SQL schema.
When I had this problem, I discovered that I had a subclass that was not mapped. In this example, some possible causes of this are:
Bus
. This is not mapped.Car
, is not mapped.In this case, ensure that every subclass is mapped:
ToTable
method call.OnModelCreating
.Alternatively, if the subclass shouldn't be mapped in the first place, ensure that it is ignored by using one of the Ignore
method calls.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With