KB Article A753
Visible to All Users

How to restore deleted objects (records)

Description:
I have deleted several records and want to restore them. Is it possible with XPO to "unerase" objects?

Answer:
Persistent objects, that are XPCustomObject or XPObject descendants, are not physically deleted from the database, but only marked as deleted. XPO creates a GCRecord column in the database table for a given persistent class. When an object is deleted, a not-NULL value is assigned to the GCRecord column. This is a Deferred Deletion feature. Its primary purpose is to avoid constraint violation when deleting associated objects.
You can restore a deleted object by reseting its GCRecord field to null (Nothing in VB.NET) via the SetValueMember method. Here is some sample code.

C#
using DevExpress.Xpo; using DevExpress.Data.Filtering; using(UnitOfWork uof = new UnitOfWork()) { ICollection col = uof.GetObjects(uof.GetClassInfo<PersistentObject1>(), new OperandProperty("GCRecord").IsNotNull(), null, 0, true, true); if(col == null || col.Count == 0) return; foreach(PersistentObject1 obj in col) { obj.SetMemberValue("GCRecord", null); } uof.CommitChanges(); }
Visual Basic
Imports DevExpress.Xpo Imports DevExpress.Data.Filtering Using uof As UnitOfWork = New UnitOfWork() Dim col As ICollection = uof.GetObjects(uof.GetClassInfo(Of PersistentObject1)(), New OperandProperty("GCRecord").IsNotNull(), _ Nothing, 0, True, True) If col Is Nothing OrElse col.Count = 0 Then Return End If For Each obj As PersistentObject1 In col obj.SetMemberValue("GCRecord", Nothing) Next uof.CommitChanges() End Using

Remarks
When a child object of a one-to-many association is deleted, XPO clears its reference to a parent object. This object remains orphan when restored. This behavior is by design, because the Deferred Deletion feature is not intended for the object restoration, but for overcoming complex foreign index constraints at the database level.
You can only restore the XPCustomObject descendants. XPBaseObject and XPLiteObject descendants are deleted immediately unless you decorate them with the DeferredDeletion attribute.
See Also:
Deferred and Immediate Object Deletion
Why are objects not deleted when I delete them in the XtraGrid?

Show previous comments (5)

    Why do you use a different random value for the GCRecord-Field to mark the child-objects as deleted? If you would use the value from the master, it might be easier to detect, which deleted child-objects had belonged to the master (although the reference isn't available). The challenge would be, to have a random and unique (for the specific class of the master-object) value …

      Frank Muelle i think its bad idea… Oid may by reuse…

      DevExpress Support Team 4 years ago

        Hello Frank,

        I created a separate ticket on your behalf: T1022100: Why Deferred Deletion does not use the GCRecord field to store a parent object when deleting child objects. We placed it in our processing queue and will process it shortly.

        Disclaimer: The information provided on DevExpress.com and affiliated web properties (including the DevExpress Support Center) is provided "as is" without warranty of any kind. Developer Express Inc disclaims all warranties, either express or implied, including the warranties of merchantability and fitness for a particular purpose. Please refer to the DevExpress.com Website Terms of Use for more information in this regard.

        Confidential Information: Developer Express Inc does not wish to receive, will not act to procure, nor will it solicit, confidential or proprietary materials and information from you through the DevExpress Support Center or its web properties. Any and all materials or information divulged during chats, email communications, online discussions, Support Center tickets, or made available to Developer Express Inc in any manner will be deemed NOT to be confidential by Developer Express Inc. Please refer to the DevExpress.com Website Terms of Use for more information in this regard.