.NET Framework 4.5.2+
.NET Framework 4.5.2+
.NET Standard 2.0+

How to: Restore Deleted Objects

  • 3 minutes to read

Persistent objects, that are XPCustomObject or XPObject descendants, are not physically deleted from a database. Instead, these objects are only marked as deleted. XPO creates a GCRecord column in a database table for a given persistent class. When an object is deleted, a not-NULL value is assigned to the corresponding GCRecord field value. This is the Deferred Deletion feature, which enables the avoidance of constraint violations when deleting associated objects.

This example demonstrates how to restore deleted objects. To do this, a null (Nothing in VB.NET) value should be assigned to the corresponding GCRecord field value via the XPBaseObject.SetMemberValue method.


When an object with Deferred Deletion enabled is deleted, it is removed from associated collections. Associations cannot be recreated automatically when you restore a deleted object. This behavior is by design, because the Deferred Deletion feature is not intended for object restoration, but for overcoming complex foreign index constraints at the database level.

Persistent Object Class Definition

First, define the Customer class. To provide for the automatic collection of changes by a Unit of Work, Simplified Property Syntax is used to code property setters.

class Customer : XPObject {
    string fName;
    int fAge;

    public Customer(Session session) : base(session) { }   

    public string Name {
        get { return fName; }
        set { SetPropertyValue(nameof(Name), ref fName, value); }

    public int Age {
        get { return fAge; }
        set { SetPropertyValue(nameof(Age), ref fAge, value); }

Restoring Deleted Objects

using System.Collections;
using DevExpress.Xpo;

private void RestoreDeletedCustomers(Session session) {
    using (NestedUnitOfWork restore = session.BeginNestedUnitOfWork()) {
        ICollection delCol = restore.GetObjects(restore.GetClassInfo<Customer>(),
            Customer.Fields.GCRecord.IsNotNull(), null, 0, true, true);
        if (delCol != null && delCol.Count != 0) {
            foreach (Customer cust in delCol) {
                cust.SetMemberValue(Customer.Fields.GCRecord.PropertyName, null);
See Also