簡體   English   中英

關系多對多 EF6 Fluent API

[英]Relation Many to Many EF6 Fluent API

我正在使用帶有 Fluent API 的 EF6 開發應用程序,但在管理多對多關系時遇到了問題。 由於某些內部原因,Join 表具有特定格式,包括 4 個字段 - Left Id (FK) - Right Id (FK) - StartDate (dateTime) - EndDate (datetime)

刪除鏈接實際上是將 EndDate 設置為不是 null 但我現在不知道如何在 EF6 中配置它。 另一方面,當讀取與 Not NULL EndDate 的記錄鏈接時,不應考慮。

你能給我一個解決方案嗎?

謝謝你。

你能給我一個解決方案嗎?

如果您的鏈接表有額外的列,您必須將 model 作為實體,並且導航的 EndDate 邏輯需要明確。 EF 不會為您做任何這些。

我不想讓它成為實體,因為 2 個額外的字段是技術字段(用於記錄目的)而不是功能字段。 我的應用程序不應該知道它們的存在。

我想知道我是否不能使用 MapToProcedure() function 但我不知道該怎么做???

連接表和 EF

EF 為您自動化了一些事情。 為此,它使用約定優於配置。 如果你遵守約定,你可以跳過一大堆常見的配置。

例如,如果您的實體有一個名為Id的屬性,EF 將固有地假定這是 PK。

同樣,如果兩種實體類型具有相互引用的導航道具(並且兩個實體之間僅存在一個直接鏈接),則 EF 將自動假定這些導航道具是單個多對多關系的兩側。 EF 將在數據庫中創建一個連接表,但它會對您隱藏它,並讓您自己處理這兩種實體類型。

由於某些內部原因,Join 表具有特定格式,包括 4 個字段 - Left Id (FK) - Right Id (FK) - StartDate (dateTime) - EndDate (datetime)

您的連接表不再符合常規和自動生成的 EF 連接表的內容。 您期望 EF 基於盲目約定無法提供的自定義配置級別,這意味着您必須顯式配置它。

其次,您擁有這些附加列的事實意味着您希望在某些時候使用這些數據(大概是為了顯示兩個實體之間的歷史關系。因此,依賴 EF 的自動連接表作為連接是沒有意義的表和它的內容將對應用程序/開發人員隱藏。

如果您不需要應用程序獲取已結束的條目,則第二個考慮可能對您無效。 但總體觀點仍然成立。

這里的解決方案是讓連接記錄成為它自己的顯式實體。 本質上,您在這里處理的不是多對多,而是處理具有兩個一對多關系(兩種實體類型中的每一種關系)的特定實體(連接元素)。

這使您能夠准確地實現您想要的。 在這種情況下,您對 EF 可以為您自動化的期望根本不適用。


軟刪除

刪除鏈接實際上是將 EndDate 設置為不是 null 但我現在不知道如何在 EF6 中配置它。

通常,這被稱為“軟刪除”行為,盡管此處可能略有不同。 在常規的軟刪除模式中,當一個條目被刪除時,數據庫會秘密地保留該條目,但應用程序不知道這一點,也不會再次看到該條目。

目前尚不清楚您是否打算讓已結束的條目仍顯示在應用程序中,例如關系歷史記錄。 如果不是這種情況,那么您的情況正是軟刪除行為。

這不是您在 model 級別上配置的內容,而是您在數據庫的SaveChanges行為中覆蓋的內容。 我如何實現軟刪除的一個簡單示例:

public override int SaveChanges()
{
    // Get all entries of the change trackes (of a given type)
    var entries = ChangeTracker.Entries<IAuditedEntity>().ToList();

    // Filter the entries that are being deleted
    foreach (var entry in entries.Where(entry.State == EntityState.Deleted))
    {
        // Change the entry so it instead updates the entry and does not delete it
        entry.Entity.DeletedOn = DateTime.Now;
        entry.State = EntityState.Modified;
    }

    return base.SaveChanges();
}

這使您可以防止刪除要應用此功能的實體,這是實現軟刪除的最安全方法,因為這可以作為來自使用此數據庫上下文的任何消費者的數據庫刪除的全部內容。

您的問題的解決方案幾乎相同。 假設您命名了您的連接實體(參見上一章) JoinEntity

public override int SaveChanges()
{
    var entries = ChangeTracker.Entries<JoinEntity>().ToList();

    // Filter the entries that are being deleted
    foreach (var entry in entries.Where(entry.State == EntityState.Deleted))
    {
        // Change the entry so it instead updates the entry and does not delete it
        entry.Entity.Ended = DateTime.Now;
        entry.State = EntityState.Modified;
    }

    return base.SaveChanges();
}

警告語

軟刪除往往是所有實體的包羅萬象(或至少是數據庫的重要部分)。 因此,像我在這里所做的那樣,在 db 上下文級別捕獲它是有意義的。

然而,如果這個實體是唯一的,因為它是軟刪除的,那么這更像是一個業務邏輯實現,而不是一個 DAL 架構。 如果您開始為不同類型的實體編寫許多自定義規則,那么 db 上下文邏輯將會變得混亂,並且使用起來不會很好,因為您需要考慮在SaveChanges期間發生的多種可能的操作。

請注意不要將應該是業務邏輯決策的內容推送給 DAL。 我不能為你畫這條線,這取決於你的上下文。 但是評估數據庫上下文是否是實現此行為的最佳位置。

暫無
暫無

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

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