Why do I need to perform a deep clone to get this code to work?
The following code works. However, it works because I end up creating a deep clone of the suppliers. If I do not perform a deep clone then we get an error suggesting that the supplier objects have changed and the attempt to amend the supplier table has failed. This only happens if the following line is run: foreach (Supplier suppliers in exceptions)
. Oddly, this occurs irrespective whether the Delete()
method is executed. Why does this happen? I开发者_StackOverflow社区 have posted the working code below for your inspection. As I say, if you try looping without deep cloning then it does not work... Any ideas?
public void DeleteSuppliers(IList<Supplier> suppliers, Int32 parentID)
{
// If a supplier has been deleted on the form we need to delete from the database.
// Get the suppliers from the database
List<Supplier> dbSuppliers = Supplier.FindAllByParentID(parentID);
// So return any suppliers that are in the database that are not now on this form
IEnumerable<Supplier> results = dbSuppliers.Where(f => !Suppliers.Any(d => d.Id == f.Id));
IList<Supplier> exceptions = null;
// code guard
if (results != null)
{
// cast as a list
IList<Supplier> tempList = (IList<Supplier>)results.ToList();
// deep clone otherwise there would be an error
exceptions = (IList<Supplier>)ObjectHelper.DeepClone(tempList);
// explicit clean up
tempList = null;
}
// Delete the exceptions from the database
if (exceptions != null)
{
// walk the suppliers that were deleted from the form
foreach (Supplier suppliers in exceptions)
{
// delete the supplier from the database
suppliers.Delete();
}
}
}
I think the error is about the collection being enumerated having changed. You're not allowed to change the collection being enumerated by a foreach statement (or anything that enumerated an IEnumerable, if I recall correctly).
But if you make a clone then the collection you're enumerating is separate from the collection being affected by the Delete.
Have you tried a shallow copy? I would think that would work just as well. A shallow copy could be created with ToArray.
I resolved the issue by reordering the execution flow. Originally, this piece of code was execute last. The error went away when I executed it first.
精彩评论