接上篇数据上下文基类是上下文接口的实现类,其给出了接口的 部分实现,具体的上下文类可以继承自上下文基类
上下文基类的代码如下:
private
bool
isInTransaction
=
false
;
private bool isDirty = false ;
private List < ScheduledAction > actions = new List < ScheduledAction > ();
private IdentityMap identityMap = new IdentityMap();
protected abstract IDataMapper < T > GetDataMapper < T > ();
protected abstract void ExecuteScheduledAction(ScheduledAction action);
#region IObjectSpaceServices Members
/// <summary>
/// Reports whether this <c> ObjectSpaceServices </c> contain any changes which must be synchronized with the database
/// </summary>
public bool IsDirty
{
get { return isDirty; }
private set { isDirty = value; }
}
/// <summary>
/// Reports whether this <c> ObjectSpaceServices </c> is working transactionally
/// </summary>
public bool IsInTransaction
{
get { return isInTransaction; }
private set { isInTransaction = value; }
}
public T GetById < T > ( object key) where T : class , new ()
{
T item = (T)identityMap.GetObject( typeof (T), key);
if (item == null )
{
item = GetDataMapper < T > ().GetByKey(key);
identityMap.PutObject(item, key);
}
return item;
}
public IList < T > GetAll < T > () where T : class , new ()
{
return GetDataMapper < T > ().GetAll();
}
public IList < T > GetAll < T > ( int pageIndex, int pageSize) where T : class , new ()
{
throw new NotImplementedException( " The method or operation is not implemented. " );
}
public IList < T > GetByCriteria < T > (Query query) where T : class , new ()
{
return GetDataMapper < T > ().GetByCriteria(query);
}
public IList < T > GetByCriteria < T > (Query query, int pageIndex, int pageSize) where T : class , new ()
{
throw new NotImplementedException( " The method or operation is not implemented. " );
}
public virtual int GetCount < T > ()
{
throw new NotImplementedException();
}
public virtual int GetCount < T > (Query query)
{
throw new NotImplementedException();
}
private void ManageAction(ScheduledAction action)
{
if ( this .IsInTransaction)
{
actions.Add(action);
}
else
{
this .ExecuteScheduledAction(action);
}
}
public void Add( object item)
{
if (item == null )
{
throw new ArgumentNullException();
}
ScheduledAction action = new ScheduledAction(item, ScheduledAction.ActionType.Create);
ManageAction(action);
}
public void Save( object item)
{
if (item == null )
{
throw new ArgumentNullException();
}
ScheduledAction action = new ScheduledAction(item, ScheduledAction.ActionType.Update);
ManageAction(action);
}
public void Delete( object item)
{
if (item == null )
{
throw new ArgumentNullException();
}
ScheduledAction action = new ScheduledAction(item, ScheduledAction.ActionType.Delete);
ManageAction(action);
}
/// <summary>
/// Begins a transaction
/// </summary>
/// <exception cref="InvalidOperationException"> Thrown if there is an already active transaction </exception>
public void BeginTransaction()
{
if ( this .IsInTransaction)
{
throw new InvalidOperationException( " A transaction is already opened " );
}
else
{
this .IsInTransaction = true ;
}
}
/// <summary>
/// Commits the active transaction
/// </summary>
/// <exception cref="InvalidOperationException"> Thrown if there isn't an active transaction </exception>
public void Commit()
{
if ( ! this .IsInTransaction)
{
throw new InvalidOperationException( " Operation requires an opened transaction " );
}
else
{
foreach (ScheduledAction action in actions)
{
DomainObject target = action.Target as DomainObject;
if (target != null && ! target.IsValid) // TODO: Enhance this
{
throw new ApplicationException( string .Format( " Validation failed for object type: {0} " , target.GetType().Name));
}
}
using (TransactionScope tx = new TransactionScope())
{
actions.ForEach( delegate (ScheduledAction action)
{
this .ExecuteScheduledAction(action);
}
);
tx.Complete();
}
actions.Clear();
this .IsInTransaction = false ;
}
}
/// <summary>
/// Rollbacks the active transaction
/// </summary>
/// <exception cref="InvalidOperationException"> Thrown if there isn't an active transaction </exception>
public void Rollback()
{
if ( ! this .IsInTransaction)
{
throw new InvalidOperationException( " Operation requires an opened transaction " );
}
else
{
this .IsInTransaction = false ;
}
}
#endregion
#region IDisposable Members
public void Dispose()
{
if ( this .IsInTransaction)
{
this .Rollback();
}
}
#endregion
}
private bool isDirty = false ;
private List < ScheduledAction > actions = new List < ScheduledAction > ();
private IdentityMap identityMap = new IdentityMap();
protected abstract IDataMapper < T > GetDataMapper < T > ();
protected abstract void ExecuteScheduledAction(ScheduledAction action);
#region IObjectSpaceServices Members
/// <summary>
/// Reports whether this <c> ObjectSpaceServices </c> contain any changes which must be synchronized with the database
/// </summary>
public bool IsDirty
{
get { return isDirty; }
private set { isDirty = value; }
}
/// <summary>
/// Reports whether this <c> ObjectSpaceServices </c> is working transactionally
/// </summary>
public bool IsInTransaction
{
get { return isInTransaction; }
private set { isInTransaction = value; }
}
public T GetById < T > ( object key) where T : class , new ()
{
T item = (T)identityMap.GetObject( typeof (T), key);
if (item == null )
{
item = GetDataMapper < T > ().GetByKey(key);
identityMap.PutObject(item, key);
}
return item;
}
public IList < T > GetAll < T > () where T : class , new ()
{
return GetDataMapper < T > ().GetAll();
}
public IList < T > GetAll < T > ( int pageIndex, int pageSize) where T : class , new ()
{
throw new NotImplementedException( " The method or operation is not implemented. " );
}
public IList < T > GetByCriteria < T > (Query query) where T : class , new ()
{
return GetDataMapper < T > ().GetByCriteria(query);
}
public IList < T > GetByCriteria < T > (Query query, int pageIndex, int pageSize) where T : class , new ()
{
throw new NotImplementedException( " The method or operation is not implemented. " );
}
public virtual int GetCount < T > ()
{
throw new NotImplementedException();
}
public virtual int GetCount < T > (Query query)
{
throw new NotImplementedException();
}
private void ManageAction(ScheduledAction action)
{
if ( this .IsInTransaction)
{
actions.Add(action);
}
else
{
this .ExecuteScheduledAction(action);
}
}
public void Add( object item)
{
if (item == null )
{
throw new ArgumentNullException();
}
ScheduledAction action = new ScheduledAction(item, ScheduledAction.ActionType.Create);
ManageAction(action);
}
public void Save( object item)
{
if (item == null )
{
throw new ArgumentNullException();
}
ScheduledAction action = new ScheduledAction(item, ScheduledAction.ActionType.Update);
ManageAction(action);
}
public void Delete( object item)
{
if (item == null )
{
throw new ArgumentNullException();
}
ScheduledAction action = new ScheduledAction(item, ScheduledAction.ActionType.Delete);
ManageAction(action);
}
/// <summary>
/// Begins a transaction
/// </summary>
/// <exception cref="InvalidOperationException"> Thrown if there is an already active transaction </exception>
public void BeginTransaction()
{
if ( this .IsInTransaction)
{
throw new InvalidOperationException( " A transaction is already opened " );
}
else
{
this .IsInTransaction = true ;
}
}
/// <summary>
/// Commits the active transaction
/// </summary>
/// <exception cref="InvalidOperationException"> Thrown if there isn't an active transaction </exception>
public void Commit()
{
if ( ! this .IsInTransaction)
{
throw new InvalidOperationException( " Operation requires an opened transaction " );
}
else
{
foreach (ScheduledAction action in actions)
{
DomainObject target = action.Target as DomainObject;
if (target != null && ! target.IsValid) // TODO: Enhance this
{
throw new ApplicationException( string .Format( " Validation failed for object type: {0} " , target.GetType().Name));
}
}
using (TransactionScope tx = new TransactionScope())
{
actions.ForEach( delegate (ScheduledAction action)
{
this .ExecuteScheduledAction(action);
}
);
tx.Complete();
}
actions.Clear();
this .IsInTransaction = false ;
}
}
/// <summary>
/// Rollbacks the active transaction
/// </summary>
/// <exception cref="InvalidOperationException"> Thrown if there isn't an active transaction </exception>
public void Rollback()
{
if ( ! this .IsInTransaction)
{
throw new InvalidOperationException( " Operation requires an opened transaction " );
}
else
{
this .IsInTransaction = false ;
}
}
#endregion
#region IDisposable Members
public void Dispose()
{
if ( this .IsInTransaction)
{
this .Rollback();
}
}
#endregion
}