使用 EF 4.1 Fluent Code First 进行按类型继承

发布于 2024-11-18 01:40:43 字数 1661 浏览 8 评论 0原文

我有一组非常简单的数据库表,例如:

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 文章!

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!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

泼猴你往哪里跑 2024-11-25 01:40:43

您读过下面的文章了吗?

这是一篇由 3 部分组成的文章,涵盖以下方法

  1. 每个层次结构表 (TPH): 通过以下方式启用多态性非规范化
    SQL 模式,并利用保存类型的类型鉴别器列
    信息。

  2. 每个类型的表(TPT): 表示“is a”(继承)
    关系作为“有”(外键)关系。

  3. 每个混凝土类别 (TPC) 的表: 丢弃多态性和
    继承关系完全来自 SQL 架构。

Have you read the following article?

It is a 3 part article covering the following approaches

  1. Table per Hierarchy (TPH): Enable polymorphism by denormalizing the
    SQL schema, and utilize a type discriminator column that holds type
    information.

  2. Table per Type (TPT): Represent "is a" (inheritance)
    relationships as "has a" (foreign key) relationships.

  3. Table per Concrete class (TPC): Discard polymorphism and
    inheritance relationships completely from the SQL schema.

鲜肉鲜肉永远不皱 2024-11-25 01:40:43

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

  1. 存在附加子类,例如 Bus。这没有映射。
  2. 子类之一(例如 Car)未映射。

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

  1. 确保子类存在映射,包括 ToTable 方法调用。
  2. 确保在 OnModelCreating 期间实际应用映射。
  3. 如果您在跟踪此问题时遇到困难,请尝试使用调试器并在所有映射代码中设置断点。

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

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:

  1. An additional subclass exists, such as Bus. This is not mapped.
  2. One of the subclasses, such as Car, is not mapped.

In this case, ensure that every subclass is mapped:

  1. Ensure a mapping exists for the subclass, including a ToTable method call.
  2. Ensure the mapping is actually being applied during OnModelCreating.
  3. If you have trouble tracking this, try using a debugger and setting breakpoints in all of the mapping code.

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文