📄 businesscollectionbase.cs
字号:
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 + -