As I discovered in my question Eagerly Load Navigation Property that is List<OfSomeBaseClass>
, it's not possible to load properties of a derived class using the EF .Include()
method (this has been suggested as a future EF feature).
I worked around this by iterating my collections that contain a mix of sibling types, individually calling
ctx.Entry(myDerivedType).Reference("PropOfDerivedType").Load();
This results in many extra round trips to the database, but at least it works.
Now I have a need to load such an object hierarchy and save it in the Session of an MVC web application. Since the DbContext
should not be part of the session, I believe I must load the object graph AsNoTracking()
, like this:
var myGraph = (from my in ctx.MyHierarchyRoot.Include("NonDerivedStuff")
.AsNoTracking()
where CONDITION select my).Single();
Question 1
Is it necessary and correct to use .AsNoTracking()
if the object graph is to be stored in Session?
I then go on to iterate through the derived siblings in the hierarchy and attempt to load them like this:
foreach (SomeBase b in myGraph.SomeCollection)
{
if (b is SomeConcreteDerivedType)
{
ctx.Entry(b).Reference("SomePropertyOfSomeConcreteDerivedType").Load();
}
}
However, since I loaded myGraph using .AsNoTracking()
, I get:
Member 'Load' cannot be called for property 'SomePropertyOfSomeConcreteDerivedType' because the entity of type 'SomeConcreteDerivedType' does not exist in the context. To add an entity to the context call the Add or Attach method of DbSet.
Question 2
Assuming the answer to Question 1 is "yes", how can I correctly load the navigation properties of derived types?