EF Code First 抽象关系?

4
我有一个类继承了一个基类,而另一个类与该基类有关联。
例如:
- 基类:动物 - 子类1:狗 - 子类2:猫 - 相关的一对多表:疫苗记录 - 一只狗可以接受多种疫苗。这是通过List<Vaccination>实现的。 - 一只猫也可以接受多种疫苗。 - 疫苗记录只能与一只动物相关联。 - 疫苗记录不知道它是与狗还是猫相关联。(狗和猫使用不冲突的GUIDs。)
没有动物表;动物是一个抽象类。但是疫苗记录只知道动物,而不知道狗。(然而,EF知道两者。)我将我的类库分为两个部分,动物和疫苗记录在核心库中,而狗在另一个引用核心库的库中。
当使用Entity Framework Code First时,疫苗记录表会得到额外的列:Dog_ID,因为狗类的List<Vaccination>显式声明创建了一个推断。因此,这个列将疫苗记录映射到狗。这本来没问题,但是我想在多种类型的动物之间共享这个额外的列。例如,我想要一个Animal_ID,可以连接到狗或猫。
由于动物是抽象的,并且没有数据库表,我可以通过流畅的语句和/或属性/特性声明来完成这个操作吗?
3个回答

3

除非您创建Animal表并与该表建立关系,否则您的Vaccination表将始终具有每种接种动物的额外FK列。 EF无法映射和高级抽象关系 - 关系必须遵循直接在数据库中创建它们的相同规则。

如果只有一些动物可以接种疫苗,则可以向层次结构添加另一个表,并与该新表建立关系(EF无法使用接口)。您将需要Table per Type映射,这会使当前EF版本中查询的性能大大降低。


"关系必须遵循与直接在数据库中创建它们相同的规则。从技术上讲,我可以在SQL Server中将一个列作为虚拟外键关联到多个表格。我希望我能在EF CF中做到这一点。" - Jon Davis
从技术上讲,您可以将一个列与多个关系相关联,但这意味着Vacation与Dog、Cat和其他任何东西都有AnimalId相关联,一旦您填写了该列,每个“父”表必须具有相同的Id记录=您的假期将始终与狗、猫等相关。 - Ladislav Mrnka
请查看我在回答中提供的带有TPT映射的链接。Animal仍然可以是抽象的。 - Ladislav Mrnka
很遗憾,这对我没有用。我将疫苗列表移动到Animal中,并将DbSet<Animal>移动到上下文中。EF创建了Animal表。但是,如果我调用context.Animals.Add(dog),我会收到一个错误(类型不匹配),所以我使用context.Set<Dog>.Add(dog),现在Animals表为空,Dogs表已满,同时Vaccinations仍然有一个Dog_ID列。我确定我做错了什么,但那篇文章似乎太模糊了,因为它只演示了通过导航属性(User->BillingData)填充DB的过程,而我存储的数据(Animal/Dog)并非嵌套的。 - Jon Davis

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映射。


谢谢。这样就可以了,但不幸的是只有少数类型的动物可以接种疫苗。我有一个接口(即ICanHaveVaccinations),它在需要支持它的继承类型上声明了支持,但没有在基类上声明。也许在疫苗接种中声明AnimalID和Animal就足够了...我会尝试一下的。 :) - Jon Davis
@stimpy77 然后在 ICanHaveVaccinations 实现中声明 Vaccinations 属性。(例如:猫,狗) - Eranga
此外,将Animal加入疫苗接种列表时,我会收到一个有关其抽象性的错误(即没有已知的派生类型),并且无法继续构建数据库。 - Jon Davis

1

因此,当我实现了当前标记为答案的内容时(最终需要创建那个动物表),我遇到了问题,因为正如我在问题中解释的那样,我有一个声明“狗”的孤立项目,并且由于这个和相关问题,我被引导到这里这里这里


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接