Castle.ActiveRecord 多對多關係 引起的錯誤處理

Castle.ActiveRecord 實體類中,若是兩個對象有 「多對多」 關係,通常的作法是將其分解爲 兩個「一對多」關係,但有時引起了 「您要刪除 或 引用 的對象#2在數據庫中不存在」的異常數據庫

 

百思不得其解,一樣的用法在「媒體引用」中一直都是正常的,爲何在「專題引用」 和「 Web欄目引用」 中就出現異常呢?c#

經過遍歷代碼發現了細微的差異:緩存

在「媒體」的業務對象加載時,爲了判斷一個對象是否能夠刪除,常查詢其被引用的 次數是多少,使用的方法是:DALMediaReference.FindCount(data) 性能

在「專題」的業務對象加載時,爲了判斷一個對象是否能夠刪除,常查詢其被引用的 次數是多少,使用的方法是:data.SubjectReferences != null && data.SubjectReferences.Count > 0 spa

 

經過對比分析,「媒體」的檢查使用是的 數據庫 查詢方法,最終會在數據中運行,而在「專題」中使用的是 「對象的引用」 ,特別是在開啓了數據加載緩存時,雖然數據庫的引用已被刪除,因爲緩存存在的緣由,內存中的引用(專題引用)對象未從引用列表(data.SubjectReferences)中刪除,因爲引用它的對象沒有及時的維護二者的關係(刪除時從二者的引用 關係中 刪除),所以在  使用 data.SubjectReferences 語句時會加載 已從數據庫中刪除的對象。code

緣由顯然已經找到,解決的辦法有以下:orm

if (data.WebCategories != null && data.WebCategories.Count > 0){
  List<DALWebInformationCategory> tempWC = new List<DALWebInformationCategory>(data.WebCategories);
  foreach(var item in tempWC)
  {
     DALCategory _Category = item.Category;
     _Category.CategoryReferences.Remove(item);
     data.WebCategories.Remove(item);
     item.Delete();
  }
}

但也引入了另外的問題:對象

     以上的解決方案 維護了緩存中的內存對象,經過ID取得對象時,沒必要執行數據庫IO,所以性能較好,但必須在全部使用 「媒體引用」、「專題引用」這樣的主對象執行刪除操做時, 必需要增長代碼來維護這些關係,所以增長了工做量,對於象「媒體引用」這樣的對象來講,工程量至關浩大,而且也 形成了 代碼侵入,使主對象過多的分心來處理這些邏輯,違反了 對象的 單一性原則。內存

      經過 查詢數據庫 判斷的方法,雖然在數據加載時都有一次數據庫IO,帶來了必定的性能損耗,但其 有效避免了上述缺點,所以仍是比較理想的選擇。ci

相關文章
相關標籤/搜索