我正在使用一个遗留系统,它为一定数量的项目实现了TPH。因此,当前的结构如下所示
Abstract Class 1 Abstract Class 2 Abstract Class 3
| | |
--------- --------- ---------
| | | | | | | | |
T1 T2 T3 T4 T5 T6 T7 T8 T9因此类型(T*)是所有表的鉴别器,但由于某些类型共享公共列,因此存在大量不同的表。问题是,所有这些项目实际上共享一个小的共同点,但没有办法将所有这些项目收集到一个集合中。实际上,层次结构实际上应该看起来更像这样。
--------------- Base Abstract 1 ----------
| | |
Abstract Class 1 Abstract Class 2 Abstract Class 3
| | |
--------- --------- ---------
| | | | | | | | |
T1 T2 T3 T4 T5 T6 T7 T8 T9因此,从本质上讲,我们有一个TPT,其中每个类型的每个表都是一个TPH。对于一个真实世界的例子,这是我们需要的。
--------------- Vehicle ---------------
| | |
Car Boat Plane
| | |
--------- --------- ---------
| | | | | | | | |
BMW Toyota Fiat T4 T5 T6 T7 T8 T9显然,最初的设计存在一些设计缺陷,没有人预料到需要在不查询3个不同表的情况下获取所有车辆的列表。所以我的问题是,在现有的结构下,有没有办法将这个新的层次结构添加到实体框架中。我在想像这样的事情
Vehicle
-------
VehicleId
TypeId (Boat, Plane, Car, etc)
ItemFK (BoatID, PlaneId, CarId)这个是可能的吗?有没有办法将这些映射到实体框架中?我似乎不能正确地匹配它们。如果我们将BoatId、PlaneId和CarId替换为VehicleId (如Conditional Mapping in Entity Framework - OR operation with TPH),似乎可以工作,但在这一点上,我们将进行真正侵入性的模式更改,这并不是一个真正的选择,我甚至不确定这是否会起作用。本质上,我需要一种方法来将现有的键映射到新的层次结构中。任何帮助都是非常感谢的。我不知所措,似乎找不到任何解决方案来回答我的问题。
发布于 2016-07-03 12:30:02
你可以使用这个结构

public class Vehicle
{
[Key]
public int Id { set; get; }
///
// common properties
///
public Car Car { set; get; }
public Boat Boat { set; get; }
public Plane Plane { set; get; }
}
public class Car
{
[Key, ForeignKey("Vehicle")]
public int VehicleId { set; get; }
public Vehicle Vehicle { set; get; }
///
// Car properties
///
}
public class Boat
{
[Key, ForeignKey("Vehicle")]
public int VehicleId { set; get; }
public Vehicle Vehicle { set; get; }
///
// Boat properties
///
}
public class Plane
{
[Key, ForeignKey("Vehicle")]
public int VehicleId { set; get; }
public Vehicle Vehicle { set; get; }
///
// Plane properties
///
}发布于 2015-08-06 14:35:53
问题是,所有这些项实际上都有一个小的共同点,但是没有办法将所有这些项都收集到一个集合中。
也许你可以让每个层次结构中的类型实现一个公共接口?由于每个层次结构都已经是一个单独的表,因此通过添加一个公共基类似乎不会获得太多好处--而且似乎不值得这么麻烦。
发布于 2015-09-29 08:13:16
可以基于您在DbContext中定义的DbSet<>来定义TPH/TPC约定。例如,您只需为每个抽象类型声明一个DbSet<>,而不是为每个派生类型T声明一个DbSet<>。然后,您可以使用相应的DbSet<>单独查询抽象类,也可以使用基本抽象类型的DbSet<>查询所有抽象类。
基抽象类必须至少定义一个字段,以便Code-First Migrations将为该类型生成一个表。要定义的最符合逻辑的字段应该是主键。然而,由于抽象类之间的PK冲突(如您在注释中所述),当前数据的迁移将无法工作。
另一种可能性是,当您查询基本抽象类型的DbSet<>时,实体框架将正确地查询所有抽象类型,即使数据库中没有用于基本抽象类型的表(因为基本抽象类型没有定义字段)。然而,我以前没有遇到过这种情况,所以我不能肯定地说它是否会工作。
https://stackoverflow.com/questions/31765006
复制相似问题