0

我试图在EF中建模一个结构,其中我们有多个实体,每个实体都有本地化内容。所有这些本地化内容都存在于一张表中。 (请参阅下面的示例)如何在实体框架核心中为备用外键建模

我遇到了一个问题,当我用流利的语法定义外键时,以及EF运行其迁移以构建数据库时,它将在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); 

更新: 下面是目前针对这个数据库运行(并已跑了多年)查询的例子,所以其安全地说,模型是不与RDB不兼容。

当我问到时,我们的DBA跟进了“这是完全可能的,它有效,因为有关系,但没有外键约束。它不是NF,但它工作得很好。

也许我在最初的问题中并不清楚,如果是这样的话,我们很抱歉。我们要做的是,建立关系模型,并允许模型上的正常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

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

你不能有一个表(Localizations)与一个字段(LKey),这是许多其他表之一的外键。关系数据库不支持这一点。数据库引擎(也是你)永远不会知道哪个表(Foo1,Foo2,... FooX)包含特定子记录LKey='ABCD'的“父”记录。

你有两个选择:

  1. 如果你的Foo表有类似的领域 - 使用Table Per Hierarchy pattern - 所有的富实体将被存储在一个物理表与类名的其他领域。
    (模式每种类型的表(TPT)每个具体类型(TPC表)将支持later)的关系

  2. 反向。使Localizations您的父母故事(与LKey密钥)和所有Foo表 - 与LKey作为外键的子。

+0

对不起,在后续的延迟。我已经用更多的上下文等更新了这个问题 – jasper