As of version 7, Entity Framework will translate the GetType() method in LINQ where clauses. This means we can more easily get specific types (excluding derived types) when querying the DB.
Let’s look at some examples based on the below Blog hierarchy …
We can see Blog is the root and has two direct derived types; RssBlog and PrivateBlog. While PrivateBlog itself has one derived type; PrivateBlogWithMFA.
Querying specific types before Entity Framework 7
Before EF 7 we had a couple of options for only getting a specific type excluding it’s descendants. Three examples below …
- Get a complete hierarchy and exclude on the service side. Potentially terrible for performance 👎 .
- Explicitly exclude derived types (and their descendants) not wanted on the DB side using ‘is’ keyword.
Can get cumbersome if there is multiple derived types.
- Explicitly check the discriminator property for a specific type and therefore excluding all descendants on the DB side. Does the job fine, but the syntax is a little ugly.
Using GetType() in Entity Framework 7 to include (or exclude) specific types
Since we can use GetType() in our LINQ where queries in EF 7 our syntax can get a little cleaner. Here’s some examples …
- Most equivalent to 3 above. Get a specific type only and exclude it’s descendants. Simple, nice syntax. Main use case for GetType() I think.
- Get multiple specific types (exclude their derived types).
- Get all types in a hierarchy excluding a specific type (BUT including it’s descendants)
The uses cases for 2 and 3 above would be less common, but it does show how GetType() gives us a cleaner way to do advanced things compared to the Entity Framework 6 and < EF 6 alternatives.
EF 7 now translating GetType() is a nice improvement which should enable lots of us to tidy up our code a bit... BUT… remember to go easy on those hierarchies.
GitHub Gist to recreate the code above
Note the difference between is and GetType() in .NET
Note that the semantics of how is (translated pre EF7) and GetType() work is based on how they are implemented in the base class library, this isn’t an ‘EF thing’.
is (and ofType) matches a type X or any derived type of X, while GetType() matches only with the specific runtime type of an instance.