Skip to main content
All docs
V25.2
  • How to: Choose the Optimal Query Splitting Behavior in Entity Framework Core

    • 4 minutes to read

    XAF does not explicitly configure query splitting behavior for EF Core DB Contexts. If you do not configure this setting in your application, it defaults to single query mode, in which EF Core uses joins to load collection property data from multiple database tables in a single query. In some cases, this mode may lead to excessive data rows loaded with some requests and result in noticeable drops in performance. In such cases, you can use split query mode. In this mode, multiple separate queries are used to load data. Refer to the following topic for more information: Single vs. Split Queries.

    To enable split query mode in your application, modify the WithDbContext method call in the code that configures the EF Core DB Context as follows:

    File: MySolution.Blazor.Server/Startup.cs., MySolution.Win/Startup.cs, MySolution.WebApi/Startup.cs

    // ...
    builder.ObjectSpaceProviders
        .AddSecuredEFCore(options => options.PreFetchReferenceProperties())
            .WithDbContext<DXApplication61.Module.BusinessObjects.DXApplication61EFCoreDbContext>((serviceProvider, options) => {
                // ...
                // This code is specific to MS SQL Server. 
                // Other databases may require different configurations for query splitting behavior.
                options.UseConnectionString(connectionString);
                options.UseSqlServer(o => o.UseQuerySplittingBehavior(QuerySplittingBehavior.SplitQuery));
                // ...
            })
            // ...
    

    Performance Considerations

    In the following example, the Department class has two collections: Employees and Positions. The code loads all Department objects from the database with their related Employee and Position collections.

    public class Department : BaseObject {
        public virtual string Name { get; set; }
        public ICollection<Employee> Employees { get; set; } = new ObservableCollection<Employee>();
        public ICollection<Position> Positions { get; set; } = new ObservableCollection<Position>();
    }
    public class Employee : BaseObject {
        public virtual string Name { get; set; }
        public virtual Department Department { get; set; }
    }
    public class Position : BaseObject {
        public virtual string Name { get; set; }
        public virtual Department Department { get; set; }
    }
    

    In this example, the database contains 10 Department objects, each with 10 Employee records and 10 Position records.

    Single Query Mode
    In this mode, XAF executes one SQL query that returns 1,000 records: 10 Department × 10 Employee × 10 Position = 1,000 records. This mode always loads data in a single query, but it produces a larger result set and increases network traffic.
    Split Query Mode
    In this mode, XAF executes multiple SQL queries, and each query loads objects of a single type. The first query loads Department objects (10 records), the second loads Employee objects (10 records), and the third loads Position objects (10 records). In total, this mode executes 3 SQL queries and returns 30 records. It reduces network traffic and memory consumption, but increases the number of round trips to the server.

    The mode you should use depends on your application’s business model architecture and network infrastructure. The following section outlines possible scenarios that can help you choose the appropriate mode for your application.

    You can set the query mode globally (as demonstrated in the code snippet at the beginning of this article) or specify it on a per-query basis:

    var data = ObjectSpace.GetObjectsQuery<Department>()
        .Include(d => d.Employees)
        .Include(d => d.Positions)
        .ToList();
    

    A Strategy to Choose the Optimal Query Splitting Mode

    The database stores many Departments (in multiples of 10). Departments have many Employees (in multiples of 10) or many Positions.
    Use the split query mode.
    There are not many Departments, and/or Departments do not have many Employees and Positions.
    Choose a mode based on your network performance. See the options below.
    Your network is fast and network latency is low.
    Use split query mode.
    Your database server hosted in a cloud service; the network is slow and has considerable latency (tens of milliseconds).
    You need to experiment with various modes.
    See Also