/// <summary>Test that Clearing a PM also clears all EntityLists.</summary>
[Test]
public void PmClearTest() {
PersistenceManager pm = new PersistenceManager(PersistenceManager.DefaultManager);
// Read some entities so we can see what we're clearing;
EntityList<Customer> custList = pm.GetEntities<Customer>();
EntityList<Order> orderList = pm.GetEntities<Order>();
EntityList<Employee> empList = new EntityList<Employee>();
empList.ListChanged += new ListChangedEventHandler(empList_ListChanged); // listen for entities coming and going
msListChangedContext = "initialize emplist"; // context in which list changed
empList.ReplaceRange(pm.GetEntities<Employee>());
int originalCount = empList.Count;
Assert.Greater(originalCount, 0, "Got no emps.");
msListChangedContext = "remove emp";
Employee anEmp = empList[0];
pm.RemoveEntity(anEmp, false);
Assert.AreEqual(anEmp.RowState, DataRowState.Detached, "Removed emp is not detached.");
Assert.AreEqual(originalCount - 1, empList.Count, "Should have had one fewer emp after remove");
anEmp.AddToManager();
msListChangedContext = "re-add emp to manager and then to list";
empList.Add(anEmp);
// Defect: I think pm.Clear should be able to clear all EntityLists that it knows about automatically.
// Because it doesn't, we use ClearAllEntities to get the job done.
// Comment out the following 2 lines to see that PM doesn't clear the EntityLists and the tests fail.
msListChangedContext = null; // Don't report list changed for as its items disappear individually
ClearAllEntities(pm); // Clear the PM entities first
msListChangedContext = "clear pm."; // Never shown because no ListChanged event on Pm.Clear()
pm.Clear();
Assert.IsTrue(empList.Count == 0, "Have emps in EntityList after PM clear.");
Assert.IsTrue(custList.Count == 0, "Have customers in EntityList after PM clear.");
Assert.IsTrue(orderList.Count == 0, "Have orders in EntityList after PM clear.");
}
#region PmClearTest Diagnostic
private static string msListChangedContext = "Unknown context";
static void empList_ListChanged(object sender, ListChangedEventArgs e) {
if ( String.IsNullOrEmpty(msListChangedContext) ) return;
Console.WriteLine("ListChanged fired in context: " + msListChangedContext);
}
#endregion
#region ClearAllEntities
/// <summary>Clears all entities in the Pm, also clearing associated EntityLists.</summary>
/// <param name="pPm">The PersistenceManager we will clear.</param>
/// <remarks>
/// This method is useful when we want to clear a PersistenceManager (PM)
/// and do not know what EntityLists contain entities currently resident in that PM.
/// <para>
/// An EntityList(Of T) cannot clear itself today
/// when we clear the PM holding entities in that list.
/// An EntityList only listens for changes to the rowstate of individual entities,
/// not to the EntityTable.TableCleared event.
/// Moreover, PersistenceManager.Clear does not clear individual EntityTables;
/// rather it simply discards the tables themselves.
/// </para>
/// <para>
/// This method iterates through all of the EntityTables of the PM
/// and removes each entity of each table.
/// </para>
/// <para>
/// This could be very slow; it would be better to keep track of our
/// EntityLists and clear them before clearing the PM.
/// However, it may not be possible to know all of the EntityLists with
/// entities in the PM we are clearing.
/// This method will take care of that because all EntityLists
/// will "hear" our removal of the individual entities.
/// </para>
/// </remarks>
private void ClearAllEntities(PersistenceManager pPm) {
pPm.QueryCache.Clear(); // Query cache should be empty after this operation
DataTableCollection pEntityTables = pPm.DataSet.Tables;
foreach ( DataTable anEntityTable in pEntityTables ) {
ClearEntityTable(anEntityTable);
}
}
/// <summary>Clears the entities of the type, T, in the Pm, also clearing associated EntityLists.</summary>
/// <typeparam name="T">The entity type to clear.</typeparam>
/// <param name="pPm">The PersistenceManager holding instances of this Entity type.</param>
private void ClearEntityType<T>(PersistenceManager pPm) where T : Entity {
EntityTable table = pPm.GetTable(typeof(T));
ClearEntityTable(table);
}
/// <summary>Clears the entities in the Entity table.</summary>
private static void ClearEntityTable(DataTable pEntityTable) {
// Diagnostic:
Console.WriteLine("Clearing EntityTable: " + pEntityTable.TableName);
// pEntityTable.Clear(); // doesn't work
// must remove each entity individually
DataRowCollection entities = pEntityTable.Rows;
for ( int i = ( entities.Count - 1 ); i >= 0; i-- ) {
entities.RemoveAt(i);
}
}
#endregion