簡體   English   中英

如何使用DbContextScope檢索saveChanges之后DB生成的ID

[英]How to retrieve ID generated by DB after saveChanges using DbContextScope

我計划創建一個具有以下層的應用程序,並將實體框架用作我的ORM:

  • 介紹 :與我的問題無關。
  • 業務 :在這一層中,我計划僅使用DTO對象。 我想將我的業務層與任何數據庫實現細節分開,因此與實體的所有交互都在DAL層中完成。
  • DAL :在這一層中,我計划擁有所有實體框架代碼和實體。 我將介紹可以由業務層調用的存儲庫。 這些存儲庫期望DTO對象作為輸入,並返回DTO對象作為輸出。 DTO和實體之間的映射是在此層中完成的。

我看了很多在線教程以及與Entity Framework相關的文章,並且遇到了DbContextScope項目,這似乎是控制“業務交易”並確保所有相關更改都已提交或回滾的非常好的解決方案。 參見GitHub: https : //github.com/mehdime/DbContextScope

該GitHub存儲庫中的演示包含一個場景,其中在數據庫中創建了一個新實體。 當我嘗試將該場景映射到我的圖層時,它看起來像這樣:

  1. 業務 :使用要存儲的實體的屬性值創建DTO。 創建新的DbContextScope並在傳遞DTO的DAL層中調用存儲庫。

  2. DAL :存儲庫將DTO映射到實體,並將其添加到實體框架的DbContext。

  3. 業務 :在DbContextScope上調用SaveChanges()方法,該方法又在實體框架的DbContext上調用SaveChanges()。

在演示中,創建DTO時已知道要存儲的實體的ID。 但是,我正在尋找一種方法來確定在業務層中調用DbContextScope上的SaveChanges()方法后由EF自動分配的ID。 由於此時我處於業務層中,因此我無法再訪問該實體,因此無法再訪問該實體的ID屬性。

我想我只能通過查詢數據庫中剛剛創建的記錄來確定ID,但這只有在原始DTO包含一些我可以用來查詢數據庫的唯一標識符的情況下才有可能。 但是,如果我在查詢的DTO中沒有唯一值怎么辦?

關於如何解決此問題的任何建議,還是您對我的圖層建議了另一種方法? (例如,也可以在業務層中使用實體-盡管這聽起來做錯了)

我盡可能使用Mehdime的上下文范圍,因為我發現它是工作單元的特殊實現。 我同意卡米洛關於不必要的分離的評論。 如果可以信任EF充當您的DAL,則應該信任它可以按設計工作,以便您可以完全利用它。

就我而言,我的控制器管理DbContextScope,並且我將存儲庫模式與DDD設計結合用於我的實體。 該存儲庫充當與DbContextLocator范圍內和定位的上下文進行交互的守門人。 在創建實體時,存儲庫通過“ Create {X}”方法充當工廠,其中{X}代表實體。 這樣可以確保提供創建實體所需的所有必需信息,並且在返回實體之前將其與DbContext關聯,以確保該實體始終處於有效狀態。 這意味着將進行上下文范圍的SaveChanges調用,綁定服務將自動為其分配ID的實體。 ViewModels / DTO是控制器返回給使用者的東西。 您還可以選擇在DbContextScope的邊界內調用DbContext的SaveChanges,這還將在上下文范圍SaveChanges之前顯示ID。 當您要為松散耦合的實體獲取ID時,這是一個非常極端的情況。 (無FK /映射關系)存儲庫還提供“刪除”代碼,以確保所有相關實體,規則等得到管理。 在編輯實體時,實體本身受DDD方法約束。

可能有一個更純粹的論點,認為這會將域或EF特定問題的細節“泄漏”到控制器中,但是我個人認為,在服務層內的受限上下文范圍內,“信任”實體和EF的好處遠遠超過其他任何東西。 它更簡單,並且為您的代碼提供了很大的靈活性,而無需使用幾乎重復的方法來向消費者提供過濾后的數據,也不需要復雜的過濾邏輯來從服務層“隱藏” EF。 我遵循的基本規則是實體絕不會在其上下文范圍的邊界之外返回。 (無需分離/重新附加,只需選擇進入ViewModels,並根據傳入的視圖模型/參數管理實體上的Create / Update / Delete。)

如果您可以提供更多特定問題/示例,請隨時添加一些概述這些問題的代碼。

暫無
暫無

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

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