• Csla框架之业务对象状态


      (若感觉以下思想存在问题,请速速离开!)

      关于对象状态的维护,开始有所体会还是在linq2sql和ef中,称作上下文的应该就会对当前所使用过的对象进行状态跟踪,无论是新建对象,还是从数据库获取对象进而对其进行更新删除操作,在上下文中都会对它们进行状态跟踪。无论是简单对象还是包含子对象的复杂对象,都应该是有状态的。同样的思想,Csla框架中也是这么来处理的(当然,可以具体的处理方法不同)。

      Csla框架中,状态的管理只对可编辑的对象有用,包括可编辑的根、子对象,可编辑的根、子对象集,还有一个就是动态可编辑对象。对于只读的对象本身就不具可编辑性,所以也谈不上状态了。

      框架中的状态属性包括:IsNew,IsSelfDirty,IsDirty,IsSelfValid,IsValid,IsSavable,IsDeleted。其中在以前的版本中没有IsSelf与IsSelfValid,其展现形式是通过用户自己来实现的,在现在的版本中因为有了字段管理功能,所以这些功能就直接实现在了框架内部,比以前方便很多。也许从名称就可以看得出各个状态的意义,以下就个人看法作小小说明:

      (状态不会独立工作,有些状态的依据是来自于其他某些的状态,如IsDirty与IsSelfDirty有关,是否可保存状态IsSavable与IsDeleted,IsNew等多个状态有关(当然也可能与对象的IsBusy状态有关);在保存时以上多个状态都会先后起作用!)

      IsNew,顾名思义,代表新对象的意思,它标识如果内存中的对象主键存在于数据库中,那么值为False,否则值为True,在框架中创建新对象时默认为True,或者旧对象被删除后,系统也会将值赋予True(内在与数据库中主键不再对应)。在保存时,如果IsNew为True,系统会调用新增方法,否则就会是修改或删除。

      IsSelfDirty(这个属性在看2.0版本时还没有),标识对象创建/获取后是否对其数据进行更新过(书上称为脏对象),所以无论是新建对象时还是对象重获取时,对象的脏状态默认是False的,当对象在对对象属性进行赋值或通过方法间接操作时,脏属性就会标识为True。IsDirty与IsSelfDirty大体一致,但IsDirty的状态还会与它的子对象的状态相关,也就是只有对象自身的IsSelfDirty为False并且所有子对象的IsDirty的状态为False时此对象的IsDrity才为False,否则当前的对象就是标识为脏的,所以每次访问该属性时它都会去遍历它的所有子对象的状态(当然如果有为True的就会直接返回),这个功能在旧版本中是在对象中通过重写IsDirty来实现的,在现在的版本中框架通过字段管理就可以自动进行跟踪(前提是属性中的子对象是通过框架内部的字段管理方式来实现的)。因为在IsDirty为False时当前对象(及子对象)是未编辑状态,所以为True时系统才会继续向下根据其他状态判断该执行什么数据操作方法,

      IsValid与IsSelfValid与脏对象原理一致,只不过是否通过验证是根据对象的数据有效性有关,只有当前对象的所有字段都有效,也就是没有违反任何规则时才为True。数据有效性及验证规则的统一管理也是框架的一个实现目标,以后再说。

      IsDeleted,标识当前对象是否被删除。框架支持直接删除和延迟删除,是否删除属性就是延迟删除进行操作的依据(注意的是子对象的的删除方法是DeleteChild(),根对象的为Delete(),不通用!),它会将当前可编辑的对象标识为IsDeleted=True,系统并不会直接提交,而是作删除标记,当用户最后调用Save()方法时系统会根据当前对象或子对象的删除状态进行调用删除方法。

      最后的是IsSavable属性,它是以上属性的集合体,标识当前对象是否可保存,在这引用一下框架属性代码:

       1:          /// <summary>
       2:          /// Returns <see langword="true" /> if this object is both dirty and valid.
       3:          /// </summary>
       4:          /// <remarks>
       5:          /// An object is considered dirty (changed) if 
       6:          /// <see cref="P:Csla.BusinessBase.IsDirty" /> returns <see langword="true" />. It is
       7:          /// considered valid if IsValid
       8:          /// returns <see langword="true" />. The IsSavable property is
       9:          /// a combination of these two properties. 
      10:          /// </remarks>
      11:          /// <returns>A value indicating if this object is both dirty and valid.</returns>
      12:          [Browsable(false)]
      13:          public virtual bool IsSavable
      14:          {
      15:              get
      16:              {
      17:                  bool auth;
      18:                  if (IsDeleted)
      19:                      auth = Csla.Security.AuthorizationRules.CanDeleteObject(this.GetType());
      20:                  else if (IsNew)
      21:                      auth = Csla.Security.AuthorizationRules.CanCreateObject(this.GetType());
      22:                  else
      23:                      auth = Csla.Security.AuthorizationRules.CanEditObject(this.GetType());
      24:                  return (auth && IsDirty && IsValid && !IsBusy);
      25:              }
      26:          }

    可以看出,除了上面的状态,还有auth和IsBusy,auth是获取对应状态下是否可操作的用户权限。至于后面的IsBusy,没注意过…

      属性的应用主要是在页面状态的控制与数据保存,如当对象IsSavable为False时让保存按钮失效,当对象是新对象时可以禁用掉删除按钮,还有个主要应用点就是保存时,上面也提到,下面也贴下代码:

       1:          /// <summary>
       2:          /// Saves the object to the database.
       3:          /// </summary>
       4:          /// <remarks>
       5:          /// <para>
       6:          /// Calling this method starts the save operation, causing the object
       7:          /// to be inserted, updated or deleted within the database based on the
       8:          /// object's current state.
       9:          /// </para><para>
      10:          /// If <see cref="Core.BusinessBase.IsDeleted" /> is <see langword="true"/>
      11:          /// the object will be deleted. Otherwise, if <see cref="Core.BusinessBase.IsNew" /> 
      12:          /// is <see langword="true"/> the object will be inserted. 
      13:          /// Otherwise the object's data will be updated in the database.
      14:          /// </para><para>
      15:          /// All this is contingent on <see cref="Core.BusinessBase.IsDirty" />. If
      16:          /// this value is <see langword="false"/>, no data operation occurs. 
      17:          /// It is also contingent on <see cref="Core.BusinessBase.IsValid" />. 
      18:          /// If this value is <see langword="false"/> an
      19:          /// exception will be thrown to indicate that the UI attempted to save an
      20:          /// invalid object.
      21:          /// </para><para>
      22:          /// It is important to note that this method returns a new version of the
      23:          /// business object that contains any data updated during the save operation.
      24:          /// You MUST update all object references to use this new version of the
      25:          /// business object in order to have access to the correct object data.
      26:          /// </para><para>
      27:          /// You can override this method to add your own custom behaviors to the save
      28:          /// operation. For instance, you may add some security checks to make sure
      29:          /// the user can save the object. If all security checks pass, you would then
      30:          /// invoke the base Save method via <c>base.Save()</c>.
      31:          /// </para>
      32:          /// </remarks>
      33:          /// <returns>A new object containing the saved values.</returns>
      34:          public virtual T Save()
      35:          {
      36:              T result;
      37:              if (this.IsChild)
      38:                  throw new NotSupportedException(Resources.NoSaveChildException);
      39:              if (EditLevel > 0)
      40:                  throw new Validation.ValidationException(Resources.NoSaveEditingException);
      41:              if (!IsValid && !IsDeleted)
      42:                  throw new Validation.ValidationException(Resources.NoSaveInvalidException);
      43:              if (IsBusy)
      44:                  throw new Validation.ValidationException(Resources.BusyObjectsMayNotBeSaved);
      45:              if (IsDirty)
      46:                  result = (T)DataPortal.Update(this);
      47:              else
      48:                  result = (T)this;
      49:              OnSaved(result, null, null);
      50:              return result;

      Over!

    作者:屈鲁奇

    出处:https://www.cnblogs.com/quluqi

    联系:496195435@qq.com QQ:496195435

    本文版权归作者和博客园共有,欢迎转载,但必须保留此段声明,且在文章页面明显位置给出原文连接。如有问题或建议,请多多赐教,非常感谢。
  • 相关阅读:
    iOS新手在引入第三方出现的几个小问题
    XMPP安装中遇到需要卸载openfire的步骤
    KVC
    SQLite错误码
    简单对象的本地化(以图片为例)
    使用MD5完成自定义Person对象的加密过程
    IOS--工作总结--post上传文件(以流的方式上传)
    IOS开发系列 --- 核心动画
    监听键盘 防止输入时覆盖掉textfiled
    比较选择的开始时间和结束时间的大小
  • 原文地址:https://www.cnblogs.com/quluqi/p/2013150.html
Copyright © 2020-2023  润新知