⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 businesscollectionbase.cs

📁 C# 版本的一个三层商业架构
💻 CS
📖 第 1 页 / 共 2 页
字号:
using System;
using System.Collections;
using System.IO;
using System.Reflection;
using System.Runtime.Serialization.Formatters.Binary;
using CSLA.Resources;

namespace CSLA
{
  /// <summary>
  /// This is the base class from which most business collection
  /// objects will be derived.
  /// </summary>
  /// <remarks>
  /// <para>
  /// To create a collection of business objects, inherit from this 
  /// class. The business objects contained in this collection must
  /// inherit from <see cref="T:CSLA.BusinessBase" />, and the objects
  /// must be marked as child objects.
  /// </para><para>
  /// Please refer to 'Expert One-on-One VB.NET Business Objects' for
  /// full details on the use of this base class to create business
  /// collections.
  /// </para>
  /// </remarks>
  [Serializable()]
  abstract public class BusinessCollectionBase : CSLA.Core.SortableCollectionBase, 
                                                 ICloneable,
                                                 Serialization.ISerializationNotification
  {
    #region Contains

    /// <summary>
    /// Used to see if the collection contains a specific child object.
    /// </summary>
    /// <remarks>
    /// Only the 'active' list of child objects is checked. 
    /// Business collections also contain deleted objects, which are
    /// not checked by this call.
    /// </remarks>
    /// <param name="Item">A reference to the object.</param>
    /// <returns>True if the collection contains the object.</returns>
    public bool Contains(BusinessBase item)
    {
      return List.Contains(item);
    }

    /// <summary>
    /// Used to see if the collection contains a reference to a
    /// child object that is marked for deletion.
    /// </summary>
    /// <remarks>
    /// This scans the list of child objects that have been marked
    /// for deletion. If this object is in that list, the method
    /// returns True.
    /// </remarks>
    /// <param name="Item">A reference to the object.</param>
    /// <returns>True if the collection contains the object.</returns>
    public bool ContainsDeleted(BusinessBase item)
    {
      foreach(BusinessBase element in deletedList)
        if(element.Equals(item))
          return true;
      return false;
    }

    #endregion

    #region IsDirty, IsValid

    /// <summary>
    /// Returns True if this object's data has been changed.
    /// </summary>
    /// <remarks>
    /// <para>
    /// When an object's data is changed, CSLA .NET makes note of that change
    /// and considers the object to be 'dirty' or changed. This value is used to
    /// optimize data updates, since an unchanged object does not need to be
    /// updated into the database. All new objects are considered dirty. All objects
    /// marked for deletion are considered dirty.
    /// </para><para>
    /// Once an object's data has been saved to the database (inserted or updated)
    /// the dirty flag is cleared and the object is considered unchanged. Objects
    /// newly loaded from the database are also considered unchanged.
    /// </para>
    /// <para>
    /// If any child object within the collection is dirty then the collection
    /// is considered to be dirty. If all child objects are unchanged, then the
    /// collection is not dirty.
    /// </para>
    /// </remarks>
    /// <returns>A value indicating if this object's data has been changed.</returns>
    public bool IsDirty
    {
      get
      {
        // any deletions make us dirty
        if(deletedList.Count > 0) 
          return true;

        // run through all the child objects
        // and if any are dirty then the
        // collection is dirty
        foreach(BusinessBase child in List)
          if(child.IsDirty)
            return true;
        return false;
      }
    }

    /// <summary>
    /// Returns True if the object is currently valid, False if the
    /// object has broken rules or is otherwise invalid.
    /// </summary>
    /// <remarks>
    /// <para>
    /// By default this property relies on the underling <see cref="T:CSLA.BrokenRules" />
    /// object to track whether any business rules are currently broken for this object.
    /// </para><para>
    /// You can override this property to provide more sophisticated
    /// implementations of the behavior. For instance, you should always override
    /// this method if your object has child objects, since the validity of this object
    /// is affected by the validity of all child objects.
    /// </para>
    /// <para>
    /// If any child object within the collection is invalid then the collection
    /// is considered to be invalid. If all child objects are valid, then the
    /// collection is valid.
    /// </para>
    /// </remarks>
    /// <returns>A value indicating if the object is currently valid.</returns>
    public bool IsValid
    {
      get
      {
        // run through all the child objects
        // and if any are invalid then the
        // collection is invalid
        foreach(BusinessBase child in List)
          if(!child.IsValid)
            return false;
        return true;
      }
    }

    #endregion
    
    #region Begin/Cancel/ApplyEdit

    /// <summary>
    /// Starts a nested edit on the object.
    /// </summary>
    /// <remarks>
    /// <para>
    /// When this method is called the object takes a snapshot of
    /// its current state (the values of its variables). This snapshot
    /// can be restored by calling <see cref="M:CSLA.BusinessBase.CancelEdit" />
    /// or committed by calling <see cref="M:CSLA.BusinessBase.ApplyEdit" />.
    /// </para><para>
    /// This is a nested operation. Each call to BeginEdit adds a new
    /// snapshot of the object's state to a stack. You should ensure that 
    /// for each call to BeginEdit there is a corresponding call to either 
    /// CancelEdit or ApplyEdit to remove that snapshot from the stack.
    /// </para><para>
    /// See Chapters 2 and 4 for details on n-level undo and state stacking.
    /// </para><para>
    /// This method triggers the copying of all child object states.
    /// </para>
    /// </remarks>
    public void BeginEdit()
    {
      if(this.IsChild)
        throw new NotSupportedException(Strings.GetResourceString("NoBeginEditChildException"));

      CopyState();
    }

    /// <summary>
    /// Cancels the current edit process, restoring the object's state to
    /// its previous values.
    /// </summary>
    /// <remarks>
    /// Calling this method causes the most recently taken snapshot of the 
    /// object's state to be restored. This resets the object's values
    /// to the point of the last <see cref="M:CSLA.BusinessCollectionBase.BeginEdit" />
    /// call.
    /// <para>
    /// This method triggers an undo in all child objects.
    /// </para>
    /// </remarks>
    public void CancelEdit()
    {
      if(this.IsChild)
        throw new NotSupportedException(Strings.GetResourceString("NoCancelEditChildException"));

      UndoChanges();

      foreach(BusinessBase child in List)
        child.AddBusinessRules();
      foreach(BusinessBase child in deletedList)
        child.AddBusinessRules();
    }

    /// <summary>
    /// Commits the current edit process.
    /// </summary>
    /// <remarks>
    /// Calling this method causes the most recently taken snapshot of the 
    /// object's state to be discarded, thus committing any changes made
    /// to the object's state since the last 
    /// <see cref="M:CSLA.BusinessCollectionBase.BeginEdit" /> call.
    /// <para>
    /// This method triggers an ApplyEdit in all child objects.
    /// </para>
    /// </remarks>
    public void ApplyEdit()
    {
      if(this.IsChild)
        throw new NotSupportedException(Strings.GetResourceString("NoApplyEditChildException"));

      AcceptChanges();
    }

    #endregion

    #region N-level undo

    internal void CopyState()
    {
      // we are going a level deeper in editing
      _editLevel += 1;

      // cascade the call to all child objects
      foreach(BusinessBase child in List)
        child.CopyState();

      // cascade the call to all deleted child objects
      foreach(BusinessBase child in deletedList)
        child.CopyState();
    }

    internal void UndoChanges()
    {
      BusinessBase child;

      // we are coming up one edit level
      _editLevel -= 1;
      if(_editLevel < 0)
        _editLevel = 0;

      // Cancel edit on all current items
      for(int index = List.Count - 1; index >= 0; index--)
      {
        child = (BusinessBase)List[index];
        child.UndoChanges();
        // if item is below its point of addition, remove
        if(child.EditLevelAdded > _editLevel)
          //List.Remove(child);
          List.RemoveAt(index);
      }

      // cancel edit on all deleted items
      for(int index = deletedList.Count - 1; index >= 0; index--)
      {
        child = (BusinessBase)deletedList[index];
        child.UndoChanges();
        if(child.EditLevelAdded > _editLevel)
        {
          // if item is below its point of addition, remove
          //deletedList.Remove(child);
          deletedList.RemoveAt(index);
        }
        else
        {
          // if item is no longer deleted move back to main list
          if(!child.IsDeleted)
            UnDeleteChild(child);
        }
      }
    }

    internal void AcceptChanges()
    {
      // we are coming up one edit level
      _editLevel -= 1;
      if(_editLevel < 0)
        _editLevel = 0;

      // cascade the call to all child objects
      foreach(BusinessBase child in List)
      {
        child.AcceptChanges();
        // if item is below its point of addition, lower point of addition
        if(child.EditLevelAdded > _editLevel)
          child.EditLevelAdded = _editLevel;
      }

      // cascade the call to all deleted child objects
      for(int index = deletedList.Count - 1; index >= 0; index--)
      {
        BusinessBase child = (BusinessBase)deletedList[index];
        child.AcceptChanges();
        // if item is below its point of addition, remove
        if(child.EditLevelAdded > _editLevel)
          //deletedList.Remove(child);
          deletedList.RemoveAt(index);
//        // if item is below its point of addition, lower point of addition
//        if(child.EditLevelAdded > _editLevel)
//          child.EditLevelAdded = _editLevel;
      }
    }

    #endregion

    #region Delete and Undelete child

    private void DeleteChild(BusinessBase child)
    {
      // mark the object as deleted
      child.DeleteChild();
      // and add it to the deleted collection for storage
      deletedList.Add(child);
    }

    private void UnDeleteChild(BusinessBase child)
    {
      // we are inserting an _existing_ object so
      // we need to preserve the object's editleveladded value
      // because it will be changed by the normal add process
      int saveLevel = child.EditLevelAdded;
      List.Add(child);
      child.EditLevelAdded = saveLevel;

      // since the object is no longer deleted, remove it from
      // the deleted collection
      deletedList.Remove(child);
    }

    #endregion

    #region DeletedCollection

    /// <summary>
    /// A collection containing all child objects marked
    /// for deletion.
    /// </summary>
    protected DeletedCollection deletedList = new DeletedCollection();

    /// <summary>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -