B2016-130: Copy and paste replace steps causing missing and duplicate items in tree (problems with ‘NextItems’)
This commit is contained in:
@@ -264,6 +264,76 @@ namespace VEPROMS.CSLA.Library
|
||||
foreach (ItemInfo tmp in _CacheByPrimaryKey[_ItemID.ToString()])
|
||||
tmp._ItemDocVersionCount = -1; // This will cause the data to be requeried
|
||||
}
|
||||
// B2016-130: GetNext was added so that NextItems was not used for finding the next item in a list of iteminfos using 'nextitems'.
|
||||
// When using 'nextitems' internal list data structures for items were not maintained consistently with the database items during
|
||||
// some occurrences of copy/paste/delete.
|
||||
[Serializable()]
|
||||
private class PreviousIDCriteria
|
||||
{
|
||||
public PreviousIDCriteria(int? previousID)
|
||||
{
|
||||
_PreviousID = previousID;
|
||||
}
|
||||
private int? _PreviousID;
|
||||
public int? PreviousID
|
||||
{
|
||||
get { return _PreviousID; }
|
||||
set { _PreviousID = value; }
|
||||
}
|
||||
}
|
||||
public ItemInfo GetNext()
|
||||
{
|
||||
try
|
||||
{
|
||||
ItemInfo tmp = DataPortal.Fetch<ItemInfo>(new PreviousIDCriteria(ItemID));
|
||||
if (tmp.ErrorMessage == "No Record Found")
|
||||
{
|
||||
tmp.Dispose(); // Clean-up ItemInfo
|
||||
tmp = null;
|
||||
}
|
||||
return tmp;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new DbCslaException("Error on ItemInfo.GetNext", ex);
|
||||
}
|
||||
}
|
||||
private void DataPortal_Fetch(PreviousIDCriteria criteria)
|
||||
{
|
||||
if (_MyLog.IsDebugEnabled) _MyLog.DebugFormat("[{0}] ItemInfo.DataPortal_FetchPreviousID", GetHashCode());
|
||||
try
|
||||
{
|
||||
using (SqlConnection cn = Database.VEPROMS_SqlConnection)
|
||||
{
|
||||
ApplicationContext.LocalContext["cn"] = cn;
|
||||
using (SqlCommand cm = cn.CreateCommand())
|
||||
{
|
||||
cm.CommandType = CommandType.StoredProcedure;
|
||||
cm.CommandText = "getNextItems";
|
||||
cm.Parameters.AddWithValue("@PreviousID", criteria.PreviousID);
|
||||
cm.CommandTimeout = Database.DefaultTimeout;
|
||||
using (SafeDataReader dr = new SafeDataReader(cm.ExecuteReader()))
|
||||
{
|
||||
if (!dr.Read())
|
||||
{
|
||||
_ErrorMessage = "No Record Found";
|
||||
return;
|
||||
}
|
||||
ReadData(dr);
|
||||
}
|
||||
}
|
||||
// removing of item only needed for local data portal
|
||||
if (ApplicationContext.ExecutionLocation == ApplicationContext.ExecutionLocations.Client)
|
||||
ApplicationContext.LocalContext.Remove("cn");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (_MyLog.IsErrorEnabled) _MyLog.Error("ItemInfo.DataPortal_FetchPreviousID", ex);
|
||||
_ErrorMessage = ex.Message;
|
||||
throw new DbCslaException("ItemInfo.DataPortal_Fetch", ex);
|
||||
}
|
||||
}
|
||||
private int _NextItemCount = 0;
|
||||
/// <summary>
|
||||
/// Count of NextItems for this Item
|
||||
@@ -578,6 +648,25 @@ namespace VEPROMS.CSLA.Library
|
||||
throw new DbCslaException("Error on ItemInfo.Get", ex);
|
||||
}
|
||||
}
|
||||
// B2016-130: Just get an item from the database, but don't add it to the cache because it gets
|
||||
// freed (only use this in a 'using' statement).
|
||||
public static ItemInfo GetNonCached(int itemID)
|
||||
{
|
||||
try
|
||||
{
|
||||
ItemInfo tmp = DataPortal.Fetch<ItemInfo>(new PKCriteria(itemID));
|
||||
if (tmp.ErrorMessage == "No Record Found")
|
||||
{
|
||||
tmp.Dispose(); // Clean-up ItemInfo
|
||||
tmp = null;
|
||||
}
|
||||
return tmp;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new DbCslaException("Error on ItemInfo.GetNonCached", ex);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
#region Data Access Portal
|
||||
internal ItemInfo(SafeDataReader dr)
|
||||
|
@@ -64,7 +64,17 @@ namespace VEPROMS.CSLA.Library
|
||||
for (int i = 0; i < Count; i++)
|
||||
{
|
||||
if (base[i] == sender)
|
||||
{
|
||||
// Added insert to fix when item is replaced and a 'delete' is done, the item needs inserted. Note
|
||||
// that when text is modified, i.e. 'Changed', this code is not executed. Fixed B2016-130.
|
||||
RefreshingList = true;
|
||||
IsReadOnly = false;
|
||||
Items.Insert(i, (sender as ItemInfo).MyPrevious);
|
||||
IsReadOnly = true;
|
||||
this.OnListChanged(new ListChangedEventArgs(ListChangedType.ItemChanged, i));
|
||||
RefreshingList = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
private bool _Disposed = false;
|
||||
|
Reference in New Issue
Block a user