EF不能很好的支援DDD?估計是我們搞錯了!

2022-01-31 21:12:29 字數 1346 閱讀 6158

題記:最近在abp專案中嘗試純粹的ddd,然後遇到ef實現的repository似乎不能很好支援ddd,但……可能是我們搞錯了。

abp即asp.net boilerplate,乙個融合了很多最佳實踐(比如領域驅動設計,domain driven design,ddd)的應用程式開發框架。當然,abp並沒有強制要求你嚴格使用ddd中的概念來開發。換句話說,也可以很好的支援ddd的概念,比如倉儲(repository)的概念(abp分別提供了entity framework和nhibernate的實現)。

abp在剛剛更新的0.13.0版本中引入了名為aggregateroot的基類,可以讓你方便的引入ddd中的聚合和聚合根的概念了。

不過我在基於聚合來實現功能的時候,遇到了乙個問題:在ef的repository實現下,聚合中的實體無法通過聚合根來正確刪除。舉例來說,假設聚合中包含order和orderline兩個實體,order是聚合根,那麼如果通過

order.orderlines.remove(orderline)
這樣的**來刪除orderline資料的話,就會報錯。類似的問題很多人其實也遇到過,比如這篇文章就詳細解釋了這種情況:當然在stackoverflow上也有很多這樣的提問。並且這個問題在2023年就被人在uservoice提出來了,而微軟一直都沒有進行改變。

一開始,我也認為這是ef存在的缺陷。但是當我再次回顧聚合和聚合根中的相關特點的時候(以下文字引用於湯雪華的博文):

同時也找出了乙個被我們常常忽視的ef特點:標識和非標識關係的區別。所謂標識關係就是:主實體(即order)的主鍵除了作為依賴實體(即orderline)的外來鍵也要成為依賴實體的主鍵的一部分(即需要混合主鍵)。非標識關係就是:主實體的主鍵只作為依賴實體的外來鍵。兩種關係的最大不同就在於:標識關係下,依賴實體不能獨立於主實體存在,刪除主實體也會刪除依賴實體(效果類似於級聯刪除),刪除關係就會刪除依賴實體。對於這一特點的詳細說明可見此msdn文件的"considerations for identifying and non-identifying relationships」。

結合ddd聚合的特點「聚合內除根以外的其他實體的唯一標識都是本地標識,也就是只要在聚合內部保持唯一即可」,以及上面提到的ef標識關係的特點「刪除關係就會刪除依賴實體」。我們可能錯怪ef了,正確做法是:應該把聚合中的非根實體設定為標識關係。這樣的建模方式即體現了orderline的id是本地標識的特性(要全域性唯一必須混合order的id),又滿足了通過聚合根來刪除明細實體的目的。

其實這是乙個很細的設計和實現問題,很多人有遇到,當然在stackoverflow也有人給出了解決方案。我這裡只是給出了一點自己的思考,意欲解釋一下這個問題出現的根源和解決方案背後的理論基礎。

QUdp不能很好支援大網路資料報情況

最近在用qt做應用程式開發,採用udp通訊模式,部分 如下 qudpsocket udpsocket udpsocket new qudpsocket this connect udpsocket,signal readyread this,slot readpendingdatagrams voi...

cf500 3,不能很好的理解

1 codeforces round 500 div.2 based on ejoi c.photo of the sky 2 解決用乙個最小矩形,把所給的不定點圍起來3 點的橫縱座標都是不確定的,盡量讓這些點的橫座標連著最近,縱座標連著最近,這是決策4 但這類題記住,首先把所有數公升排序,然後,用...

煩躁ExtJs的panel不能很好的相容ie8

ext.onready function collapsible true,tbar bbar buttons html 定義右邊面板 var panelright new ext.panel collapsible true,disable false,hidden true,titlecolla...