4

我有一个类继承了另一个类有关系的基类。EF代码第一抽象关系?

实施例:

  • 基类:动物
  • 子类1:狗
  • 子类2:猫
  • 相关一个一对多表:接种
    • 狗可具有多次接种疫苗。这被实施为清单<疫苗接种>。
    • 一只猫可以有多次接种疫苗。
    • 疫苗接种记录只能有一个与之相关的动物。
    • 疫苗接种不知道它是否与狗或猫有关。 (狗和猫使用非冲突的GUID)

没有动物表;动物是一个抽象类。但疫苗接种只知道动物,而不知道狗。 (然而,EF知道这两者。)我将我的类库拆分为Animal和Vaccination在核心库中,Dog在另一个引用核心库的库中。

当使用实体框架代码首先,疫苗接种表获得额外的列:Dog_ID,作为Dog类的列表<疫苗接种>显式声明正在创建一个推论。因此,这一栏将疫苗接种记录映射到狗身上。这很好,除了我想分享多个类型的动物的额外列。因此,例如,如果没有Dog_ID和Cat_ID,我想要有一个可以加入狗或猫的Animal_ID。

由于动物是抽象的,没有数据库表,我可以用流利的语句和/或属性/属性声明来实现吗?

回答

3

对于每个接种类型的动物,您的Vaccination表格总是会有额外的FK列,除非您创建Animal表格并与该表格建立关系。 EF无法映射和高层次的关系抽象 - 关系必须遵循相同的规则,就像直接在数据库中创建它们一样。

如果只有一些动物可以接种疫苗,您可以添加另一个表到层次结构并与该新表关联(EF无法使用接口)。你将需要Table per Type映射,它会使当前EF版本中的查询性能变得更糟。

+0

”关系必须遵循相同的规则,就像直接在数据库中创建它们一样。“从技术上讲,我可以将一列作为虚拟外键与SQL Server中的多个表联系起来。我希望我可以在EF CF中做到这一点。 –

+0

从技术上讲,你可以关联多个关系中的一列,但这将意味着度假有AnimalId与狗,猫和其他任何相关,并且一旦你填写该列,每个“父”表必须有相同的记录ID =你的假期将永远相关的狗,猫,... –

+0

检查我在答案中提供的TPT映射的链接。动物仍然是抽象的。 –

2

假设你所有的动物都会有疫苗接种

public abstract class Animal 
{ 
    public string ID { get; set; } 
    public ICollection<Vaccination> Vaccinations { get; set; } 
} 

public class Vaccination 
{ 
    public string ID { get; set; } 
    public string AnimalID { get; set; } 
    public virtual Animal Animal { get; set; } 
    //other properties 
} 

然后你就可以继承CatDog和使用Table per Type映射。

+0

谢谢。这很好,但不幸的是只有几种动物可以接种疫苗。我有一个接口(即ICanHaveVaccinations),它在需要它的继承类型上声明它的支持,但不在基类上。虽然......我会试试看,但是在疫苗接种方面宣布AnimalID和Animal也许就足够了。 :) –

+0

@ stimpy77然后在'ICanHaveVaccinations'实现中声明'Vaccinations'属性。 (例如:猫,狗) – Eranga

+0

是的,我已经有了。 –

1

所以当我实现了当前标记为答案(我最终需要继续并创建动物表)的时候,我遇到了问题,因为正如我在我的问题中解释的那样,我有一个单独的项目声明了“狗“,对于这个和相关问题,我指导hereherehere