Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to load only base type in Entity Framework

Consider following case:

I have base class inherited by another two. For instance we will have:

class Base
{

}
class DerivedA : Base
{

}
class DerivedB : Base
{

}

When I request base entity with code like

context.Base.Where(q => q.Id == id).First();

Entity Framework generate a full set of joins to every derived entity which results in below acceptable perfomance of query. What I want is to load only base entity without joining it to derived ones.

The only solution I found described here http://blogs.msdn.com/b/alexj/archive/2009/09/17/tip-35-how-to-write-oftypeonly-tentity.aspx. But that did not work for me. EF still generates huge query.

Writing queries like:

context.Base.Where(q => !(q is DerivedA) && !(q is DerivedB)).First();

doesn't suits me either due to constantly increasing amount of derived types.

Are there any possible solutions apart from those I mentioned?

like image 565
DeeRain Avatar asked Jul 19 '12 15:07

DeeRain


1 Answers

You are using Table-per-type => EF must generate those joins because it doesn't know what type your entity really is. If your record from Base has a related record in DerivedA table IT MUST NOT create instance of Base entity for that record - IT MUST create instance of DerivedA and it needs to make joins to get this knowledge.

It is for a long discussion why this is not allowed but simply entity is from object world - it is atomic data structure which can be saved to multiple tables but that is invisible to object world. If you persist a Base you will load back a Base but if you persist DerivedA you will always load back DerivedA and never just Base because it would break the atomicity of the entity.

I didn't try it but I assume that ESQL OFTYPE ONLY operator should do joins as well to make sure that it really loads real instances of the base entity instead of corrupted instances of derived entities.

Table-per-type produces slow queries. .NET 4.5 should improve it but I think improvements will not target these cases - I think they will target OfType for derived types and projections.

If you want only data from Base table your best options are:

  • Hand written SQL - projections in .NET 4.0 still do some unnecessary joins or unions
  • .NET 4.5 and projection in Linq
like image 191
Ladislav Mrnka Avatar answered Oct 13 '22 10:10

Ladislav Mrnka