Entity Framework 3.1 Gotchas

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.

References

https://github.com/dotnet/efcore/issues/18091

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.