views:

267

answers:

3

If I have three classes in entity framework.

class Base {}

class Left : Base {}

class Right : Base {}

and I call DBContext.Bases.ToList();

This returns all instances of Base fully typed into their associated inherited types, as some people have noticed, the performance of EF on large inheritance structures is not great to say the least. My actual query in my project is 600 lines long, just for returning one entity and takes 2 seconds to generate.

They query runs much faster if you tell it which type to return, as it does not have to join across the whole structure. e.g.

DBContext.Bases.OfType<Left>.ToList();
or
DBContext.Bases.OfType<Right>.ToList();

However I now want to ONLY return the base class. Unfortunalty doing

DBContext.Bases.OfType<Base>.ToList(); 

does the same as DBContext.Bases.ToList();

It gets the WHOLE inheritance structure... Is there any way (without making a new type in EF) of ONLY returning the class Base when looking through the Base collection?

A: 

Assuming you are able to use LINQ, could you use something along the lines of the following quick and dirty example?:

var result = from item in DBContext.Bases.ToList()
            where (!item.GetType().IsSubclassOf(typeof(Base)))
           select item;
S.Robins
`GetType()`, unfortunately, isn't supported in LINQ to Entities. :(
Craig Stuntz
Hmmm... Strange. I would have thought that a ToList() would have meant that the return type would have been in the form of an IEnumerable, which LINQ would be quite happy with. And as for the issue of GetType() not being supported, that's a little more alarming. Am I mistaken here, or is this an example of a serious omission in the framework?
S.Robins
No, I missed the `ToList`. But now you're in L2O (rather than L2E), so the DB server returns all rows instead of doing it on the DB server (as `OfType<T>()` does). The query you give will work, albeit slowly. `GetType()` isn't supported because no CLR method is supported unless there is a specific SQL translation for it; see http://msdn.microsoft.com/en-us/library/bb738681.aspx for a full list. I wish `GetType()` were supported, but `Type` has a lot of features, so this would be no small task for the EF to do.
Craig Stuntz
+1  A: 

This is, unfortunately, harder than you might expect, at least in LINQ to Entities. In Entity SQL you can use OFTYPE(ONLY...). Alex James explains how to do it in this tip.

Craig Stuntz
A: 

Sorry I cant log into my actual account...

Maybe I didnt make myself clear, I want to bring back all the objects (including Base, Left and Right) but I only want the Base class to be returned, even if in the database they are actual Left and Right classes.

OFTYPE was a good suggestion but it filters out all my entities because none are the actual Base type. But I want to return only the Base type values in the Base type object.

Any ideas?

James
You cannot store an instance in one type and get a different *entity type* back when you query. I'm not sure why you'd even want to do such a thing.
Craig Stuntz
I only want the bottom part of the entity because in this particular instance that is all the information I need. If you've used the entity framework you know that doing a query like this across a wide inheritance structure gives horrible performance, which is why I only want to return just the base data in this instance.
James