簡體   English   中英

ASP.NET Core 2:在這種情況下,“多對一”關系背后的代碼是什么?

[英]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非常明確並且為每種類型強制執行單個值,但它還要求您為每個(患者)屬性提供(類)屬性。 因此,如果您稍后擴展模型,則必須調整患者模型。

選項1

選項2的好處是它可以收集所有東西。 因此,您可以向患者添加屬性,而無需在以后引入新屬性時修改模型。 此外,它還可以直接支持單一種類的多種選擇。 在缺點方面,它不會自行驗證任何內容,因此您需要業務邏輯來實際執行您的規則。

選項2


轉到數據庫,對於選項2,你顯然需要一個鏈接表,因為這是一個多對多的關系。 由於您只有一個基本類型PatientProperty的鏈接,但您實際上想要討論具體類型,您將需要某種鑒別器 鑒別器基本上只是另外在數據庫中存儲對象類型的表示法。

使用繼承存儲數據時,通常所做的是“每層次表”。 這意味着PatientProperty基本類型的層次結構中的PatientProperty類型將共享同一個表。 鑒別器列用於指定類型,並且某些屬性類型可能具有的其他屬性使用可空列實現。 此設置與Entity Framework一起開箱即用,並在本章的文檔中進行了描述

EF Core不支持另一種方法“每個類型的表”,所以如果你想遵循它,你必須自己實現它。 但在你的情況下,屬性類型大多非常相似,我實際上會反對,並實際上將它們保存在同一個表中。

對於選項1,只要您只為患者分配了每種類型的單一屬性,事情就會簡單一些。 由於那里沒有多對多,因此實際上並不需要鏈接表。 您只需要在患者模型中存儲每個鏈接屬性類型的id,如上面的UML所示。 這樣做,您還可以將屬性類型保留為不共享數據庫中的單個表的單獨類型。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM