我试图在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
答案 0 :(得分:1)
您正在尝试实现与关系数据库绝对不兼容的数据结构。
您不能拥有一个表(Localizations
),其中一个字段(LKey
)是许多其他表之一的外键。关系数据库不支持此功能。数据库引擎(你也是)永远不知道哪个表(Foo1,Foo2,... FooX)包含&#34; parent&#34;记录特定儿童记录LKey='ABCD'
。
您有两种选择:
如果您的Foo表具有相似的字段 - 使用Table Per Hierarchy pattern - 您的所有Foo实体将存储在一个物理表中,并附加带有类名的字段。
(支持每种类型的模式表格(TPT)和每种具体类型的表格(TPC) later)
反向关系的方向。将Localizations
作为您的父级故事(使用LKey
密钥)和所有Foo
表格 - 将LKey
作为外键的儿童。