【发布时间】:2018-01-03 07:56:08
【问题描述】:
我有一组非常简单的数据库表,例如:
Vehicle
Id
RegNo
Car
Id (FK of Vehicle.Id)
OtherStuff
Bike
Id (FK of Vehicle.Id)
MoreStuff
我的类模型如你所料:Vehicle 是一个抽象类,然后 Car 和 Bike 是它的子类。
我的 EF4.1 Code First 配置如下:
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);
}
}
但是,当 EF 尝试构建其模型配置时,我遇到了许多奇怪的异常。
目前它正在抛出这个:
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'.
从哪里获得该列名?它不在我的任何代码或数据库本身中。一定是某种惯例接管了控制权。如何指示 EF 使用 table-per-type?
如果我从 Vehicle 类中删除“abstract”关键字(我在某处进行了健全性测试),那么我会得到一个不同的异常,如下所示:
(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.
我显然做错了什么,但是什么?我已经关注了 MSDN 文档以及我能找到的所有其他 TPT + EF4.1 文章!
【问题讨论】:
-
您是否真的在派生的
DbContext的OnModelCreating中添加了这些配置?modelBuilder.Configurations.Add(new VehicleConfiguration());之类的东西应该在那里。不知何故,EF 似乎会使用默认继承映射,即 TPH 而不是 TPT。如果你这样做,你能显示类定义吗? -
@Slauma,是的,EntityTypeConfiguration 都已正确添加到 DbContext。别担心。类定义简单得离谱,无非就是:
public 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; } } -
您能否在代码中的 3
ToTable行设置断点,以检查您是否真的到达了它们。基本上ToTable说:“TPT”。没有 ToTable EF 将使用 TPH。 EF 以某种方式查询“鉴别器”列这一事实意味着它假定 TPH 继承。您能否显示完整的DbContext定义以及发生异常的确切代码。您现在显示的代码是正确的imo,我相信问题出在其他地方。您是在创建新数据库还是使用现有数据库?你有任何Database.SetInitializer电话吗? -
我想我已经弄清楚是什么原因造成的。我设置了一个完全独立的测试项目,并做了最少的代码,它按预期工作。但是,一旦我在模型中添加了一个新的 Vehicle 子类,但它既没有作为数据库中的表出现,也没有在 EF 映射中配置。 EF 开始抛出“映射片段中的问题......”异常。我的子类被标记为
internal,而其他的是public,所以我真的不明白为什么EF 甚至知道它存在!有什么方法可以让 EF 完全忽略这个对我的模型来说是“特例”的子类? -
如果您想从 EF 模型中排除类
Foo,您可以将[NotMapped]属性放在类上或在 Fluent API 中使用modelBuilder.Ignore<Foo>();。
标签: entity-framework entity-framework-4 entity-framework-4.1 entity-framework-6 table-per-type