zoukankan      html  css  js  c++  java
  • Castle.ActiveRecord 多对多关系 引发的错误处理

    Castle.ActiveRecord 实体类中,如果两个对象有 “多对多” 关系,一般的做法是将其分解为 两个“一对多”关系,但有时引发了 “您要删除 或 引用 的对象#2在数据库中不存在”的异常

    百思不得其解,同样的用法在“媒体引用”中一直都是正常的,为什么在“专题引用” 和“ Web栏目引用” 中就出现异常呢?

    通过遍历代码发现了细微的差别:

    在“媒体”的业务对象加载时,为了判断一个对象是否可以删除,常查询其被引用的 次数是多少,使用的方法是:DALMediaReference.FindCount(data) 

    在“专题”的业务对象加载时,为了判断一个对象是否可以删除,常查询其被引用的 次数是多少,使用的方法是:data.SubjectReferences != null && data.SubjectReferences.Count > 0 

    通过对比分析,“媒体”的检查使用是的 数据库 查询方法,最终会在数据中运行,而在“专题”中使用的是 “对象的引用” ,特别是在开启了数据加载缓存时,虽然数据库的引用已被删除,由于缓存存在的原因,内存中的引用(专题引用)对象未从引用列表(data.SubjectReferences)中删除,由于引用它的对象没有及时的维护两者的关系(删除时从两者的引用 关系中 删除),因此在  使用 data.SubjectReferences 语句时会加载 已从数据库中删除的对象。

    原因显然已经找到,解决的办法有如下:

    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,带来了一定的性能损耗,但其 有效避免了上述缺点,因此还是比较理想的选择。

  • 相关阅读:
    【转】软件测试流程详解
    【转】web网站常用功能测试点总结
    【转】【Selenium】 selenium 使用教程详解-java版本
    【转】TestNG使用详解
    【转】数据驱动和关键字驱动简单例子
    【转】【Selenium】Selenium 八种元素定位方法
    【Appium】解决No Chromedriver found that can automate Chrome '70.0.3538'
    【Appium】查看andriod内置浏览器webview版本
    【转】Appium自动化测试遇到的chromedriver/chrome坑
    🍖Flask四剑客及简单使用
  • 原文地址:https://www.cnblogs.com/yyj/p/4271065.html
Copyright © 2011-2022 走看看