使用EF 4.1 Fluent Code First的每类型表继承

nbe*_*ans 8 entity-framework table-per-type entity-framework-4 entity-framework-4.1 entity-framework-6

我有一组相当简单的数据库表,例如:

Vehicle
 Id
 RegNo

Car
 Id (FK of Vehicle.Id)
 OtherStuff

Bike
 Id (FK of Vehicle.Id)
 MoreStuff
Run Code Online (Sandbox Code Playgroud)

我的类模型正如您所期望的那样: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);
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,当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'.
Run Code Online (Sandbox Code Playgroud)

它从哪里获取列名?它不在我的任何代码或数据库本身.它必须是一些接管控制的惯例.如何指示EF使用每个表格类型?

如果我从我的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.
Run Code Online (Sandbox Code Playgroud)

我显然做了一件非常糟糕的事情,但是什么呢?我已经关注了MSDN文档以及我能找到的所有其他TPT + EF4.1文章!

thm*_*msn 8

你看过下面的文章了吗?

这是一篇包含以下方法的3部分文章

  1. 每个层次结构表(TPH):通过对SQL模式进行非规范化来启用多态,并使用包含类型信息的类型鉴别器列.

  2. 每种类型的表(TPT):将 "是一个"(继承)关系表示为"具有"(外键)关系.

  3. 每个Concrete类的表(TPC):完全从SQL模式中丢弃多态和继承关系.


Sam*_*Sam 8

当我遇到这个问题时,我发现我有一个未映射的子类.在此示例中,一些可能的原因是:

  1. 存在另一个子类,例如Bus.这没有映射.
  2. 其中一个子类(例如Car)未映射.

在这种情况下,请确保映射每个子类:

  1. 确保子类存在映射,包括ToTable方法调用.
  2. 确保实际执行映射OnModelCreating.
  3. 如果您无法跟踪此问题,请尝试使用调试器并在所有映射代码中设置断点.

或者,如果不应该首先映射子类,请确保使用其中一个Ignore方法调用忽略它.