[英]ASP.NET Core 2: What could be the code behind a “many-to-one” relationship in this case?
我在實體框架的幫助下,在ASP .NET Core 2應用程序中准備項目的數據結構( 代碼優先 )。 這種特殊的關系,我沒有經驗:用戶必須能夠選擇具有復選框的疾病,我們有類似的選擇:癌症類型,飲食等。
我有兩個以上的表,如圖片中的表,將從UserKitProperties表中引用。 此表應該像連接器表一樣工作,將用戶實體與其他實體連接起來。
userid1 | cancertypeid1
userid2 | dietaryid1
userid1 | cancertypeid2
userid3 | dietaryid1
如何在代碼中指定,以支持這種關系? 我正在考慮做一個基類,也許可以參考那個id。 這是連接器類..
public class PatientProperties : EntityModel
{
[Key]
public long ID { get; set; }
public long PatientID { get; set; }
[ForeignKey("PatientID")]
public Patient Patients { get; set; }
// this should be used for cancer type, dietary, etc..
public long PropertyID { get; set; }
/* Instead of using two classes' ids, maybe call the base class' id
[ForeignKey("PropertyID")]
public CancerType CancerTypes { get; set; }
[ForeignKey("PropertyID")]
public Dietary Dietaries { get; set; } */
}
提前感謝您的建議! :)
以下應該有效:
public class Property
{
public long PropertyId { get; set; }
}
public class CancerType : Property
{
// Your code
}
public class Dietary : Property
{
// Your code
}
public class PatientProperties : EntityModel
{
[Key]
public long ID { get; set; }
public long PatientID { get; set; }
[ForeignKey("PatientID")]
public Patient Patients { get; set; }
public long PropertyID { get; set; }
[ForeignKey("PropertyID")]
public Property Property { get; set; }
}
但是正如MS 文檔所提到的,設置這樣的繼承將在基類表中使用特殊的Discriminator列來表示存儲在一行中的特定類型。
我個人會求助於可空字段,以免增加復雜性。 但是,這並不強制PatientProperties
只有一個屬性,這是一個相當大的減:
public class PatientProperties : EntityModel
{
[Key]
public long ID { get; set; }
public long PatientID { get; set; }
[ForeignKey("PatientID")]
public Patient Patients { get; set; }
public long? CancerTypeID { get; set; }
[ForeignKey("CancerTypeID")]
public CancerType CancerType { get; set; }
public long? DietaryID { get; set; }
[ForeignKey("DietaryID")]
public Dietary Dietary { get; set; }
}
您應該考慮如何在代碼中表示這種關系,而不是首先考慮數據庫布局。 畢竟,您正在采用代碼優先的方法。
您可以選擇兩種選擇:患者有多個屬性,每種屬性類型一個,或者所有屬性只有一個集合:
public class Patient
{
// …
// option 1
public CancerType CancerType { get; set; }
public Dietary Dietary { get; set; }
public OtherProperty OtherProperty { get; set; }
// option 2
public IList<PatientProperty> Properties { get; set; }
}
這兩種選擇都有其優點和缺點。 雖然選項1非常明確並且為每種類型強制執行單個值,但它還要求您為每個(患者)屬性提供(類)屬性。 因此,如果您稍后擴展模型,則必須調整患者模型。
選項2的好處是它可以收集所有東西。 因此,您可以向患者添加屬性,而無需在以后引入新屬性時修改模型。 此外,它還可以直接支持單一種類的多種選擇。 在缺點方面,它不會自行驗證任何內容,因此您需要業務邏輯來實際執行您的規則。
轉到數據庫,對於選項2,你顯然需要一個鏈接表,因為這是一個多對多的關系。 由於您只有一個基本類型PatientProperty
的鏈接,但您實際上想要討論具體類型,您將需要某種鑒別器 。 鑒別器基本上只是另外在數據庫中存儲對象類型的表示法。
使用繼承存儲數據時,通常所做的是“每層次表”。 這意味着PatientProperty
基本類型的層次結構中的PatientProperty
類型將共享同一個表。 鑒別器列用於指定類型,並且某些屬性類型可能具有的其他屬性使用可空列實現。 此設置與Entity Framework一起開箱即用,並在本章的文檔中進行了描述 。
EF Core不支持另一種方法“每個類型的表”,所以如果你想遵循它,你必須自己實現它。 但在你的情況下,屬性類型大多非常相似,我實際上會反對,並實際上將它們保存在同一個表中。
對於選項1,只要您只為患者分配了每種類型的單一屬性,事情就會簡單一些。 由於那里沒有多對多,因此實際上並不需要鏈接表。 您只需要在患者模型中存儲每個鏈接屬性類型的id,如上面的UML所示。 這樣做,您還可以將屬性類型保留為不共享數據庫中的單個表的單獨類型。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.