Querying Specifc Inheritance Types in Entity Framework

Querying Specifc Inheritance Types in Entity Framework

Blake Anderton
//

The Problem

When using Entity Framework let’s say you set up a model with inheritance. Let’s make ourselves a simple example (with psuedo-code) to illustrate:

abstract class Product
{
int Id { get; private set; }
ICollection Items { get; set; }
}
class Good : Product { }
class Service : Product { }

class ProductItem
{
int Id { get; private set; }
string Name { get; set; }

//assume we have a navigation property
Product Product { get; set; }
int ProductId { get; set; }
}

Basically we have our inherited entity Product, and another entity ProductItem that has a navigation property to a Product. Now if you were to want to query products of only a certain type (say we only want to load services, like our company’s delicious duo of  “Bacon Frying” and “Bacon Delivery” services), you might do something like this (using LINQ, assuming a DataContext/ObjectContext named ctx):

IQueryable = from s in ctx.Products.OfType() select s;

That’s all standard, well, and good. But what if you want to query from the ProductItem’s point of view so we can query item’s properties easier? You could of course do something like this:

IQueryable = from s in ctx.Products.OfType().Include("Items") where s.Items.Any(i => i.Name.Contains("bacon")) select s;

but….there are still times you want to query starting with the items. Something like this:

IQueryable = from i in ctx.ProductItems.Include("Product") select i;

How do we do this except restrict ourselves to only loading items for services? OfType only works on collections, not navigation properies….

A Solution

The solution I found ended up being surprisingly simple – so simple it took me a long time to figure it out as I originally thought there was no way it would work:

IQueryable = from i in ctx.ProductItems.Include("Product") where (i.Product as Service) != null && i.Name.Contains("bacon") select i;

You simply cast the navigation property with the “as” keyword and check for null. This works as you would expect- Entity Framework detects this and adds the SQL to filter when the product type is a service only. I’ve only tested this with a TPH (Type per Hierarchy) strategy but I would expect it to work with TPT (Type per Table) as well. Color me impressed.

Sugoi Kantandane…

Related

Need Expert Help?

See Our Full Menu of Data Services

InterWorks uses cookies to allow us to better understand how the site is used. By continuing to use this site, you consent to this policy. Review Policy OK

×

Interworks GmbH
Ratinger Straße 9
40213 Düsseldorf
Germany
Geschäftsführer: Mel Stephenson

Kontaktaufnahme: markus@interworks.eu
Telefon: +49 (0)211 5408 5301

Amtsgericht Düsseldorf HRB 79752
UstldNr: DE 313 353 072

×

Love our blog? You should see our emails. Sign up for our newsletter!