如何在Entity Framework Core中建模备用外键

时间:2017-06-16 10:01:50

标签: entity-framework-core foreign-key-relationship ef-migrations

我试图在EF中建模一个结构,我们有多个实体,每个实体都有本地化内容。所有这些本地化内容都存在于一个表中。 (见下面的例子)

我遇到了一个问题,当我使用流利的语法定义外键时,当EF运行其迁移以构建数据库时,它将在Localization表中的LKey字段上应用多个外键。即FK_Localization_Foo1_LKey / FK_Localization_Foo2_LKey。 这是不正确的,因为现在无法将任何记录插入本地化表。

如何阻止此行为,或者我应该更改哪些内容以实现我在EF中寻找的内容?

P.S。我已经看到了建议创建中间表的示例,其中只包含LKey作为其主键,其他表引用了这一点。如果可能的话,我想避免这种情况让我们的DBA满意。

  public class Foo
  {
      ...
      [Required][StringLength(5)]
      public string LKey { get; set; }
      public ICollection<Localization> Localizations { get; set; }
  }
  // many entities similar to 'foo' with the same navigation

  public class Localization
  {
      public int LocalizationId { get; set; }

      [Required][StringLength(5)]
      public string LKey { get; set; }
      [Required][StringLength(10)]
      public string LangISO { get; set; }
      ...
  }

// inside the OnModelCreating method, there are multiple entries like the below, one for each 'Foo' type entity above

 modelBuilder.Entity<Foo>()
    .HasMany(pt => pt.Localizations)
    .WithOne()
    .HasPrincipalKey(pt => pt.LKey)
    .HasForeignKey(l => l.LKey);

更新 下面是当前针对此DB运行的查询示例(并已运行多年),因此可以肯定地说,该模型与RDB不兼容。

当我去询问时,我们的DBA跟进了#34;这绝对是可能的。它有效,因为存在关系,但没有外键约束。它不是NF,但它的工作正常。&#34;

也许我在最初的问题中并不清楚,如果是这样的话,道歉。我们要做的是模拟关系,并允许模型上的正常EF导航(这样做)使用上面的代码),但有迁移创建FKeys。

select f1.Foo1Id, ll.Text from Foo1 f1
inner join LocalizationLanguage ll on ll.DescriptionKey = f1.DescriptionKey

select f2.Foo2Id, ll.Text from Foo2 f2
inner join LocalizationLanguage ll on ll.DescriptionKey = f2.DescriptionKey

1 个答案:

答案 0 :(得分:1)

您正在尝试实现与关系数据库绝对不兼容的数据结构。

您不能拥有一个表(Localizations),其中一个字段(LKey)是许多其他表之一的外键。关系数据库不支持此功能。数据库引擎(你也是)永远不知道哪个表(Foo1,Foo2,... FooX)包含&#34; parent&#34;记录特定儿童记录LKey='ABCD'

您有两种选择:

  1. 如果您的Foo表具有相似的字段 - 使用Table Per Hierarchy pattern - 您的所有Foo实体将存储在一个物理表中,并附加带有类名的字段。
    (支持每种类型的模式表格(TPT)和每种具体类型的表格(TPC) later

  2. 反向关系的方向。将Localizations作为您的父级故事(使用LKey密钥)和所有Foo表格 - 将LKey作为外键的儿童。