Severin Meyer
06.26.2012
Show all comments
-
I am afraid that we cannot give you any suggestions, because the source of the problem is unclear. Would you please provide a sample project or database backup with business classes for us to research?
-
I was hoping there were a possibility to call the PurgeDeletedObjects() on a single object. So I would then be able to Log the XPO and SQL calls especially for this process.
Unfortunately the project is complex and I haven't the time for creating a sample. But is there a description of the PurgeDeletedObjects(), so I can see which logic is used on a record which has GCRecord != null. In which order it should be called on descendant tables and so on? -
I have now investigated the SQL-statements processed from PurgeDeleteObjects(). Some of them are returning a record, but there is no delete statement. I was thinking, that PurgeDeleteObjects will collect all objects which can be purged, and will then call delete on every found record.
-
Thank you for the additional information. I am forwarding your ticket to our developers. We will let you know if we have any ideas regarding the cause of the problem.
-
Our developers suppose that the issue is in objects that reference objects that cannot be deleted. You can find these objects via the following code:
public static class GCRootsFindHelper { public static IEnumerable FindRoots(IXPSimpleObject theObject) { return FindRoots(theObject.Session, theObject); } public static IEnumerable FindRoots(Session session, params object[] objects) { return FindRoots(session, (IEnumerable)objects); } public static IEnumerable FindRoots(Session session, IEnumerable notPurgedObjects) { ArrayList rv = new ArrayList(); ArrayList toProcess = new ArrayList(notPurgedObjects.Cast<object>().ToArray()); ObjectSet processed = new ObjectSet(); while(toProcess.Count > 0) { object o = toProcess[toProcess.Count - 1]; toProcess.RemoveAt(toProcess.Count - 1); if(processed.Contains(o)) continue; processed.Add(o); if(session.IsObjectMarkedDeleted(o)) { foreach(object r in session.CollectReferencingObjects(o, PersistentCriteriaEvaluationBehavior.InTransaction, true)) { if(!processed.Contains(r)) toProcess.Add(r); } } else { rv.Add(o); } } return rv; } }Hope this helps. -
This function was really helpful. You should consider to add it directly on the session object.
I could find out, that an older object instance is not deleted when overwritten:private LocalizedString localizedInformation;
[Aggregated]
public LocalizedString LocalizedInformation
{
get { return localizedInformation; }
set
{
if (localizedInformation != null && localizedInformation != value)
{
// Delete old string.
localizedInformation.Delete();
}
SetPropertyValue<LocalizedString>("LocalizedInformation", ref localizedInformation, value);
}
}If I don't add the Delete() method, the old value when setting the property will not be deleted.
Is this by design? -
Thank you for your idea. I will pass it to our developers.
Aggregated references are not deleted by default when the property value is changed. If one requires this logic, he/she needs to take care of this, as you did in your code snippet. -
But this is what I have asked DevExpress longtime ago, and the answer was, if the property is attributed with [Aggregated], the objects will be deleted. And I was using this approach with simpler objects, and they were deleted.
Is [Aggregated] obsolete now? -
I think there was some kind of misunderstanding about this attribute. The Aggregated deletes related objects only when the master object is deleted. In spite of the fact that, most probably, this functionality worked in a previous version as you described, it was not designed to operate in such a manner. The [Aggregated] attribute is not obsolete, it still works just as described in our documentation. Should you have any additional questions in this regard, do not hesitate to contact me.
I have also posted an Answer, so that you can close this ticket.
You must
log in
or
register
to leave comments
1 Solution
You can determine what objects prevent record deletion via the following code:
[C#]public static class GCRootsFindHelper { public static IEnumerable FindRoots(IXPSimpleObject theObject) { return FindRoots(theObject.Session, theObject); } public static IEnumerable FindRoots(Session session, params object[] objects) { return FindRoots(session, (IEnumerable)objects); } public static IEnumerable FindRoots(Session session, IEnumerable notPurgedObjects) { ArrayList rv = new ArrayList(); ArrayList toProcess = new ArrayList(notPurgedObjects.Cast<object>().ToArray()); ObjectSet processed = new ObjectSet(); while(toProcess.Count > 0) { object o = toProcess[toProcess.Count - 1]; toProcess.RemoveAt(toProcess.Count - 1); if(processed.Contains(o)) continue; processed.Add(o); if(session.IsObjectMarkedDeleted(o)) { foreach(object r in session.CollectReferencingObjects(o, PersistentCriteriaEvaluationBehavior.InTransaction, true)) { if(!processed.Contains(r)) toProcess.Add(r); } } else { rv.Add(o); } } return rv; } }
Is your intention to post an answer to your own question?
- If so, then proceed.
- If you simply wanted to post additional information, ask for further clarification, or to just say "Thanks!", please click Leave a Comment.
- If you wish to edit your original question, please use the Edit button in the Toolbox at the top right corner of that entry.
Facebook
Twitter
Google+