Skip to main content

Upcasting (Combine Data from Base and Derived Classes)

  • 4 minutes to read

This topic demonstrates how to use Upcasting in XAF. This functionality is useful when you need to combine base and derived classes in a single query.

We suggest that you implement the following business model for this example:

UpCasing1

  1. Expand the MySolution.Module project and right-click the Business Objects folder. Choose Add | Class…. Specify UpcastingDataModel.cs as the new class name and click Add. Replace the auto-generated code with the following class declaration:

    using System;
    using DevExpress.Persistent.Base;
    using DevExpress.Persistent.BaseImpl.EF;
    using System.Collections.ObjectModel;
    
    namespace MySolution.Module.BusinessObjects {
       [DefaultClassOptions]
       [System.ComponentModel.DefaultProperty(nameof(Title))]
       public class Department : BaseObject {
          public virtual string Title { get; set; }
          public virtual string Office { get; set; }
          public virtual ICollection<EmployeeBase> Employees { get; set; } = new ObservableCollection<EmployeeBase>();
       }
    
       public abstract class EmployeeBase : BaseObject {
          public virtual string Name { get; set; }
          public virtual string Email { get; set; }
          public virtual Department Department { get; set; }
       }
    
       [DefaultClassOptions]
       public class LocalEmployee : EmployeeBase {
          public virtual string InsurancePolicyNumber { get; set; }
       }
    
       [DefaultClassOptions]
       public class ForeignEmployee : EmployeeBase {
          public virtual DateTime VisaExpirationDate {  get; set; }
       }
    }
    

    Tip

    The Department, LocalEmployee and ForeignEmployee classes use the DefaultClassOptions attribute. For more information about this attribute, refer to the Data Annotations in Data Model topic.

  2. If your application uses Entity Framework Core, register the following classes in the DbContext:

    File: MySolution.Module\BusinessObjects\MySolutionDbContext

    using MySolution.Module.BusinessObjects;
    
    namespace  MySolution.Module.BusinessObjects {
       public class MySolutionEFCoreDbContext : DbContext {
          //...
          public DbSet<Department> Departments { get; set; }
          public DbSet<ForeignEmployee> ForeignEmployees { get; set; }
          public DbSet<LocalEmployee> LocalEmployees { get; set; }
       }
    }
    
  3. Run the application and invoke the Department Detail View:

    XAF ASP.NET Core Blazor - Detail View Before Configuration, DevExpress

    The nested Employees List View only displays the EmployeeBase class’s properties by default. Upcasting allows you to also display the Employee class descendant-specific properties.

  4. To add required columns, invoke the Model Editor. Navigate to the Views | MySolution.Module.BusinessObjects | EmployeeBase | Department_Employees_ListView | Columns node. Use the context menu to add two child nodes and assign the following values to the PropertyName properties of these nodes:

    • <LocalEmployee>InsurancePolicyNumber
    • <ForeignEmployee>VisaExpirationDate

    XAF recognizes these values and displays the LocalEmployee.InsurancePolicyNumber and ForeignEmployee.VisaExpirationDate properties for the objects retrieved from the database to populate the Department.Employees collection.

  5. Run the application and invoke the Department Detail View. XAF now displays the properties of the EmployeeBase class and its descendants.

    XAF ASP.NET Core Blazor - Detail View After Configuration, DevExpress