Skip to main content

Delete Persistent Objects

  • 4 minutes to read

The eXpress Persistent Objects library supports deferred and immediate object deletion.

#Delete a Persistent Object

To delete a persistent object, call the XPBaseObject.Delete method:

public void DeleteByKey(int employeeKey){
    using(var uow = new UnitOfWork()){
        // Get an object
        var employee = uow.GetObjectByKey<Employee>(employeeKey);
        // Delete the object
        employee.Delete();
        // Alternative:
        // uow.Delete(employee);
        uow.CommitChanges();
    }
}

#Delete a Collection of Objects

To delete a collection of persistent objects, call the Session.Delete(ICollection) method:

public void DeleteCustomersWithZeroOrders(){
    using(var uow = new UnitOfWork()){
        // Get a collection of Customers with 0 orders
        var customersWithZeroOrders = uow.Query<Customer>().Where(c => c.Orders.Count == 0).ToList();
        // Delete the collection
        uow.Delete(customersWithZeroOrders);
        uow.CommitChanges();
    }
}

#Deferred Object Deletion

If the XPObject or XPCustomObject is used as the base class for persistent objects, deferred deletion is enabled. This means that when you delete an object, XPO does not physically remove the corresponding record from the underlying data store. Instead, it marks the record as deleted. This technique avoids database exceptions when deleting objects that are referenced by other objects.

By default, objects marked as deleted are never retrieved from the object store unless they are referenced directly. A delete operation also deletes all aggregated objects (see AggregatedAttribute).

You can also use the Session.Delete method to delete persistent objects. This method accepts a collection as a parameter and calls the XPBaseObject.Delete method for each object in the collection. The Session.PurgeDeletedObjects method will delete objects marked as deleted, along with all corresponding records from the data store.

Note

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.

#Immediate Object Deletion

If you use XPBaseObject as the base class for persistent objects, immediate object deletion is enabled. In this instance, records corresponding to deleted objects are physically deleted. Note that object deletion requires extra steps when you work with many-to-many relationships. An attempt to delete an object throws an exception, because the hidden intermediate object references the object. Clear all references to the object before deletion.

Note

To enable deferred object deletion, apply the DeferredDeletionAttribute.

Note

The functionality described here is demonstrated in the Data Exchange and Manipulation | Deleting Persistent Objects section of the XPO Tutorials demo (C:\Users\Public\Documents\DevExpress Demos 24.1\Components\WinForms\Bin\XpoTutorials.exe).

#Restore Deleted Objects

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 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.

Note

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.

using System.Collections;
using DevExpress.Xpo;

private void RestoreDeletedCustomers(Session session) {
    // "Customer" is an XPObject descendant
    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);
            }
            restore.CommitChanges();
        }
    }
}

#Member Table

#Online Knowledge Base

See Also