Search code examples
c#entity-frameworkentity-framework-corelinqkit

Load related data with EF Core 3.1


I'm not sure if I'm doing something wrong or if this is a bug in EF Core 3.1 but the following works with EF 6.x and is part of a Generic Repository which I'm converting to EF Core 3.1:

  IQueryable<TEntity> query = this.Context.Set<TEntity>();

  if (filter != null)
  {
      query = query.AsExpandable().Where(filter);
  }

  if (includeProperties != null)
  {
      foreach (var includeProperty in includeProperties.Split(new[] { ',' },
                                      StringSplitOptions.RemoveEmptyEntries))
      {
          query = query.Include(includeProperty);
      }
  }

but it doesn't work in EF Core 3.1

I've tried changing my "Roles" properties from virtual to a regular public property but no change and the weird thing is that if I call the following code in my data layer before call the above code:

var test = this.Context
               .Users
               .Include(u => u.Roles)
               .FirstOrDefault(f => f.Username == "[email protected]");

it works as expected and then if I execute the problematic code, it loads my roles as expected.

Any ideas?

Thanks


Solution

  • It's more LinqKit AsExpandable problem, although is caused by strange EF Core requirement which LinqKit is failing/not willing to implement even in its EF Core dedicated version LinqKit.Microsoft.EntityFrameworkCore.

    The problem is that LinqKit uses its own query provider, but EF Core ignores Include and some other EF Core queryable extensions if the query provider is not what they expect (class derived from EntityQueryProvider).

    The workaround is to move all EF Core specific methods like Include, ThenInclude, AsNoTracking etc. before AsExpandable. Or don't use AsExpandable at all, call manually Expand() on expressions which need it, e.g. instead of

        query = query.AsExpandable().Where(filter);        
    

    use

        query = query.Where(filter.Expand());