Skip to main content
All docs
V24.2
.NET 8.0+

Soft Deletion (Deferred Object Deletion)

  • 3 minutes to read

XAF UI and Web API Service-powered apps support EF Core soft (deferred) deletion. If you use this deletion mode, the ORM does not immediately remove the corresponding record from the database. Instead, it marks the record as deleted. This technique avoids database exceptions when you delete objects referenced by other entities.

How It Works

EF Core business classes can implement the IDeferredDeletion interface that declares an integer GCRecord property. As a result, database tables for such classes contain GCRecord columns. When an object is marked for deletion, XAF generates a random integer value for it and writes it to GCRecord. XAF checks GCRecord values when it loads data for List and Detail Views, reports, and in other similar situations. DevExpress.Persistent.BaseImpl.EF.BaseObject and all other built-in XAF business classes (for example, PermissionPolicyUser and FileData) already implement IDeferredDeletion and support this functionality out of the box.

Enable Soft Deletion

Configure Your Project’s DBContext

Newly created projects
If you used our Solution Wizard, your application already supports deferred deletion functionality on the DBContext level (the UseDeferredDeletion method). In this case, proceed to the next step: Enable Deferred Deletion in Custom Entity Classes.
Existing projects created with XAF versions before v24.2

In the OnModelCreating method of your DBContext, call the UseDeferredDeletion method:

File: YourSolutionName.Module\BusinessObjects\YourSolutionNameDbContext.cs

using DevExpress.ExpressApp.Design;
using DevExpress.ExpressApp.EFCore.DesignTime;
using DevExpress.Persistent.BaseImpl.EF;
using DevExpress.Persistent.BaseImpl.EF.PermissionPolicy;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Design;

namespace YourSolutionName.Module.BusinessObjects;

public class YourSolutionNameDbContext : DbContext {
    protected override void OnModelCreating(ModelBuilder modelBuilder) {
        base.OnModelCreating(modelBuilder);
        modelBuilder.UseDeferredDeletion(this);
        // ...
    }
}

Enable Deferred Deletion in Custom Entity Classes

Recommended technique
Derive your custom entity class from DevExpress.Persistent.BaseImpl.EF.BaseObject and inherit the GCRecord property.
Advanced technique

Implement the IDeferredDeletion interface in your entity class and add a GCRecord property:

using DevExpress.Persistent.BaseImpl.EF;

namespace YourSolutionName.Module.BusinessObjects;

public class YourCustomEntity : IDeferredDeletion {
    // ...
    public virtual string Name { get; set; }
    public int GCRecord { get; set; }
}

Add the GCRecord Column To Existing Database Tables

If you already mapped your business classes to an existing database, use the automatic converter. For more information, refer to the following Breaking Change ticket in our Support Center: Core - Database and data model code changes for XAF EF Core apps to support Soft/Deferred Deletion

Disable Soft Deletion

To disable soft deletion for the entire application, remove the UseDeferredDeletion method from the OnModelCreating method in your your DBContext.

File: YourSolutionName.Module\BusinessObjects\YourSolutionNameDbContext.cs

using DevExpress.ExpressApp.Design;
using DevExpress.ExpressApp.EFCore.DesignTime;
using DevExpress.Persistent.BaseImpl.EF;
using DevExpress.Persistent.BaseImpl.EF.PermissionPolicy;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Design;

namespace YourSolutionName.Module.BusinessObjects;

public class YourSolutionNameDbContext : DbContext {
    protected override void OnModelCreating(ModelBuilder modelBuilder) {
        base.OnModelCreating(modelBuilder);
        // Remove this line from your code.
        modelBuilder.UseDeferredDeletion(this);
        // ...
    }
}

To disable soft deletion for a specific class, decorate it with the DisableDeferredDeletion attribute:

using DevExpress.Persistent.BaseImpl.EF;

namespace YourSolutionName.Module.BusinessObjects;

[DisableDeferredDeletion]
public class YourCustomEntity : BaseObject {
    public virtual string Name { get; set; }
}

Purge Deleted Objects from SQL Server Database

To purge deleted objects from a table, use the following script:

DELETE FROM table_name
WHERE GCRecord = '1'

To purge deleted objects from all tables, use the following script:

DECLARE @sql NVARCHAR(MAX) = '';

SELECT @sql = @sql + 'DELETE FROM ' + table_name + ' WHERE GCRecord = 1'
FROM information_schema.columns
WHERE column_name = 'GCRecord';

EXEC sp_executesql @sql;