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!
OnModelCreating
of your derivedDbContext
? Something likemodelBuilder.Configurations.Add(new VehicleConfiguration());
etc. should be there. Somehow it looks as if EF would use default inheritance mapping which is TPH and not TPT. If you do, could you show the class definitions. – Bunkpublic abstract class Vehicle { public Guid Id { get; set; } public String RegNo { get; set; } } public class Car : Vehicle { public String OtherStuff { get; set;} } public class Bike : Vehicle { public String MoreStuff { get; set; } }
– KarenToTable
lines in your code to check if you really reach them. BasicallyToTable
says: "TPT". Without ToTable EF would use TPH. The fact that EF is somehow querying for a column "Discriminator" means that it assumes TPH inheritance. And can you show your fullDbContext
definition and the code where exactly the exception occurs. The code you are showing right now is correct imo, I believe that the problem is somewhere else. Are you creating a new DB or using an existing one? Do you have anyDatabase.SetInitializer
call? – Bunkinternal
, whereas the others arepublic
, so I don't really see why EF even knows it exists! Is there some way to make EF totally ignore this subclass that is a "special case" for my model? – Karen[NotMapped]
attribute on the class or use in Fluent APImodelBuilder.Ignore<Foo>();
if you want to exclude the classFoo
from the EF model. – Bunk