Search code examples
c#entity-framework-coredbcontext

API to ask EF Core DBContext to ignore some AutoIncluded entities?


In the EF Core 7 DbContext class, in UpdateNavigationLoading, I have some AutoInclude calls:

private static void UpdateNavigationLoading(ModelBuilder modelBuilder){
{
    modelBuilder.Entity<Order>()
                .Navigation(order => order.OrderItems)
                .AutoInclude();

    modelBuilder.Entity<OrderItem>()
                .Navigation(orderItem => orderItem.Item)
                .AutoInclude();
    // ... etc
}

But in one of my API calls, I do not wish to include the Item entity to be returned with any OrderItem records.

In the base service, I eventually basically end up at:

return context.Set<Order>().AsQueryable(); 

Beyond this, to that returned IQueryable from AsQueryable(), I add some where clauses, etc, like:

if (StartDate.HasValue)
{
    query = query.Where(item => item.Created >= filter.StartDate);
}

or add a limit:

if (Limit.HasValue)
{
    query = query.Take(Limit.Value);
}

and you can imagine more, I'm sure..

But because of what's in the modelbuilder UpdateNavigationLoading call, the OrderItem's Item entity is auto-included.

Without changing the UpdateNavigationLoading call, is there a way I can indicate to, or ask the DbContext at the API service level to not honour the AutoInclude of the OrderItem.Item?

So in my call to

context.Set<Order>().AsQueryable();

or before that call, can I set something in the DbContext to do what I need?


Solution

  • In EF Core 7, there is no direct built-in functionality to ignore or disable specific auto-included entities at the API service level without modifying the UpdateNavigationLoading method. However, you can achieve the desired behavior by using a combination of Include and IgnoreAutoIncludes methods.

    Here's an example of how you can modify your API service code to exclude the Item entity from being auto-included for OrderItem:

    using Microsoft.EntityFrameworkCore;
    
    // ...
    
    public IQueryable<Order> GetOrders(DbContext context, DateTime? startDate, int? limit)
    {
        var query = context.Set<Order>().AsQueryable();
    
        // Apply custom filters
        if (startDate.HasValue)
        {
            query = query.Where(item => item.Created >= startDate);
        }
    
        if (limit.HasValue)
        {
            query = query.Take(limit.Value);
        }
    
        // Disable auto-includes temporarily
        query = query.IgnoreAutoIncludes();
    
        // Include only necessary entities
        query = query.Include(order => order.OrderItems).ThenInclude(orderItem => orderItem.PropertyA)
                     // Add more includes if needed
                     // .Include(order => order.OtherEntity)
    
        return query;
    }
    

    In the code above, we first call IgnoreAutoIncludes on the IQueryable<Order> object to disable auto-includes for subsequent queries. Then, we use the Include method to explicitly specify the entities you want to include. By not including the Item entity, it won't be auto-included when fetching OrderItem records.

    Remember to adjust the Include calls based on your entity structure and relationships.

    Note: The IgnoreAutoIncludes method is not available in EF Core 5 or earlier versions. It was introduced in EF Core 6. So, if you are using an older version, this approach won't work, and you may need to modify the UpdateNavigationLoading method or consider other alternatives.