簡體   English   中英

如何防止實體框架創建雙外鍵

[英]How to prevent Entity Framework from creating double Foreign Keys

我在使用代碼先從我的實體創建數據庫時遇到了麻煩。 請考慮兩個類。 CourseTn課程

    public class CourseTn
{
    // Pk
    public CourseLevel CourseTnId { get; set; }

    // Properties
    public string Title { get; set; }
    public virtual List<CourseTnImage> CourseImage { get; set; }
    public virtual List<ChapterTn> Chapters { get; set; }

    public AdministratorTnAccount AdministratorTnAccount { get; set; }
    public Guid? AdministratorTnAccountId { get; set; }

    public ClientTnAccount ClientTnAccount { get; set; }
    public Guid? ClientTnAccountId { get; set; }

}

和ChapterTn類

public class ChapterTn
{
    // Pk
    public int ChapterTnId { get; set; }

    // Properties
    public string ChapterName { get; set; }
    public virtual List<ChapterTnImage> ChapterImage { get; set; }
    public virtual List<SectionTn> Sections { get; set; }

    // FK

    public virtual CourseTn CourseTn { get; set; }
    public CourseLevel CourseTnId { get; set; }
}

courseTnId在ChapterTn類中指定為外鍵。 第一個問題是,Entitiy Framework似乎並沒有重組該約定,而是將courseTnId映射為一個屬性。

第二個問題是,Enitity Framework為CourseTn創建了兩個FK,一個為null,另一個為非null。 請看下面的圖片

在此處輸入圖片說明

有沒有一種方法可以使Entity Framework識別ChapterTn類中courseTnId的常規指定FK?

您的PK不能是CourseLevel復雜類型。 和您的FK一樣。 請嘗試以下方法:

    public class CourseTn
    {
        // Pk
        public int CourseTnId { get; set; }

        // Properties
        public string Title { get; set; }
        public virtual List<CourseTnImage> CourseImage { get; set; }
        public virtual List<ChapterTn> Chapters { get; set; }

        public AdministratorTnAccount AdministratorTnAccount { get; set; }
        public Guid? AdministratorTnAccountId { get; set; }

        public ClientTnAccount ClientTnAccount { get; set; }
        public Guid? ClientTnAccountId { get; set; }

    }

    public class ChapterTn
    {
        // Pk
        public int ChapterTnId { get; set; }

        // Properties
        public string ChapterName { get; set; }
        public virtual List<ChapterTnImage> ChapterImage { get; set; }
        public virtual List<SectionTn> Sections { get; set; }

        // FK
        public virtual CourseTn CourseTn { get; set; }
        public int CourseTnId { get; set; }
    }

另外,你可以用力FK識別與屬性CourseTnIdChapterTn類。
[ForeignKey("CourseTn"), Column(Order = 0)]

您計划在CourseChapter之間設計一對多的關系:每個Course都有零個或多個Chapters ,每個Chapter恰好屬於一個Course

由於某些原因,您決定偏離實體框架的代碼優先約定 ,因此不得不使用屬性或流暢的API對此進行更正。

為什么您的“多對多”集合類列表而不是ICollections? Course.Chapters[4]真的Course.Chapters[4]嗎? 此外,您確定要限制自己使用包含真正章節列表的課程嗎? 當然不是,因為在您的課程內部甚至沒有章節列表。 內部有兩個帶有外鍵的表。 因此它不是列表。 最多可以添加一個元素,並可以請求元素的數量:不是列表,而是ICollection。

出於某種原因,您課程的主鍵類型是CourseLevel。 您確定在設計中無法想象兩個課程可能具有相同的CourseLevel嗎? 而且您確定,在將課程添加到數據庫之前,您不知道其課程級別嗎? 課程會變得越來越難或更容易,從而改變其CourseLevel嗎? 通過嘗試使用數據庫標識符進行一些棘手的事情,您獲得了什么好處?

此外,我認為這是導致您出現問題的原因:盡管為章節提供了值CourseId您卻忘記告訴實體框架這是本章課程的外鍵。

以下內容足以解決您的所有問題。

class Course
{
    public int Id {get; set;}
    // every Course has zero or more Chapters:
    public virtual ICollection<Chapter> Chapters {get; set;}

    // other properties:
    public CourseLevel Level {get; set;}
    ...
}

class Chapter
{
    public int Id {get; set;}

    // every Chapter belongs to exactly one Course using foreign key
    public int CourseId {get; set;}
    public virtual Course Course {get; set;}

    ... // other properties
}

因為我遵循了實體框架一對多的約定 ,所以這是所有實體框架需要了解的用於配置兩個表以及主鍵和外鍵的所有知識。 不需要屬性,也不需要流利的API。

我還將主鍵更改為更常規的類型,如果您確實有很好的論據可以按自己的方式操作,請嘗試一下並查看它是否有效。

暫無
暫無

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

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