![](/img/trans.png)
[英]EF6 - TPH foreign key mapping in derived classes using base class property
[英]How to Automatically Map TPH Derived Classes in EF Core?
默認情況下,EF6 將 map 為基礎抽象 class 及其為每個層次結構表 (TPH) 的派生類。
EF Core 不再遵循此邏輯,並要求選擇加入派生類。文檔指出:
按照慣例,在上下文的 DbSet 屬性中公開的類型作為實體包含在 model 中。 還包括在 OnModelCreating 方法中指定的實體類型,以及通過遞歸探索其他已發現實體類型的導航屬性找到的任何類型。
如果您有幾個子類型,則使用這種方法並不難,因為您可以將它們添加為 DbSet 或為每個子類型添加 HasDiscriminator().HasValue(),映射如下:
builder.HasDiscriminator()
.HasValue<CommaSymbolRule>("CommaSymbolRule")
.HasValue<DashSymbolRule>("DashSymbolRule")
.HasValue<IsNumericSymbolRule>("IsNumericSymbolRule")
.HasValue<IsPunctuationSymbolRule>("IsPunctuationSymbolRule")
.HasValue<PeriodSymbolRule>("PeriodSymbolRule")
在某些情況下,這是次優的,因為您可能有許多派生類。 就我而言,我有一個規則引擎,不想讓 map 每個規則單獨使用。
有沒有辦法在 EF Core Table Per Hierarchy 場景中自動 map 基本 class 的子類型,而無需手動添加它們?
我認為在 EF Core 中可能有一種方法可以做到這一點,但發現沒有。
我與 EF 團隊討論了為什么自動選擇不再是默認設置,他們對可能非常有效的“程序集掃描解決方案”的穩定性表示擔憂。 目前,他們似乎對按照這些思路添加新功能不太感興趣。
這是我想出的。 它將程序集掃描放入映射代碼中,但似乎有效。
首先,我創建了一個擴展方法來獲取派生類(它可以選擇按名稱忽略特定類型):
public static Type[] GetDerivedClasses(this Type type, string[] ignoreTypeNames = null)
{
ignoreTypeNames = ignoreTypeNames ?? new string[0];
return Assembly.GetAssembly(type)
.GetTypes()
.Where
(
t => t.IsSubclassOf(type) &&
(!ignoreTypeNames?.Any(t.Name.Contains) ?? false)
)
.OrderBy(o => o.Name)
.ToArray();
}
然后對 EF Core 映射中的基本 class 使用與此類似的代碼,切換您的類型(即:此代碼中的“SymbolRule”):
public void Configure(EntityTypeBuilder<SymbolRule> builder)
{
builder.ToTable("SymbolRule"); // my example table
builder.HasKey(t => t.SymbolRuleId); // my example key
foreach (var type in typeof(SymbolRule).GetDerivedClasses())
{
builder.HasDiscriminator()
.HasValue(type, type.Name);
}
}
foreach 從基類 class 獲取派生類,並遍歷它們並為每個類添加一個鑒別器類型。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.