I’ve recently been upgrading an EF Core 2.x project to EF Core 3.1. In doing so, I came across the issues in this post. Hopefully, next time, I’ll look here first!
Include has changed
If you’re using .include
in a lambda that’s based on a DbSet, you may have something akin to the following:
var result = animals .Select(a => a.Name) .Where(a => a.Type.Name == "Duck") .Include(a => a.Type) .ToList();
Whilst this does work in EF 2.x, it will not work in 3.x; you’ll may get the following error:
System.InvalidOperationException: ‘Include has been used on non entity queryable.’
The issue here is that you’re restricted as to how you can use Includes. You’ll need to use something more like this:
var ducks = animals .Include(a => a.Type) .Select(a => a.Name) .Where(a => a.Type.Name == "Duck") .ToList();
Should you wish to include multiple related entities, you can use the following syntax:
var ducks = animals .Include(a => a.Type) .ThenInclude(a => a.EnvironmentInformation) .Select(a => a.Name) .Where(a => a.Type.Name == "Duck") .ToList();
Beware of Unions
Unions don’t actually work in Entity Framework Core. They never have. What this means, is that in 2.1, when you issues this type of command:
var ducks = animals .Include(a => a.Type) .Select(a => a.Name) .Where(a => a.Type.Name == "Duck"); var geese = animals .Include(a => a.Type) .Select(a => a.Name) .Where(a => a.Type.Name == "Goose"); var combined = geese .Union(ducks);
What actually happened was that the two queries would be run, the results brought down to the client and joined there. In 3.x, you get something like the following error:
System.InvalidOperationException: ‘Set operations over different store types are currently unsupported’
Essentially, what this forces you to do is ether explicitly bring the results down to the client yourself:
var ducks = animals .Include(a => a.Type) .Select(a => a.Name) .Where(a => a.Type.Name == "Duck") .ToList();
Or run the query on the server by employing something like a Stored Procedure.