Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

The abstract type X has no mapped descendants and so cannot be mapped

I have the following model :

public abstract class AbstractBase { }
public abstract class AbstractBase<T> : AbstractBase where T : SomeOtherTypeBase
{
    T MyProp {get; set;}
}
public class Concrete1 : AbstractBase<OtherTypeSpecializationFor1> { }
public class Concrete2 : AbstractBase<OtherTypeSpecializationFor2> { }

But entity framework gives me the error :

The abstract type AbstractBase has no mapped descendants and so cannot be mapped

In my opinion this should not happen since AbstractBase directly inherits from AbstractBase and the classes Concrete1/2 which are concrete inherit from GenericAbstractBase. What's going on here ?

Also, just out of curiosity, I'm wondering if the property of type T in GenericAbstractBase would be persisted by EF, just in case someone passing by has the answer in mind.

Update 1

Can anyone confirm that this is supported by EF ? I've seen this post and according to Rowan's answer's this should be the case. Thank you

Update 2 Same issue when the generic base class is not abstract.

like image 730
tobiak777 Avatar asked Mar 22 '15 17:03

tobiak777


1 Answers

Here is the answer from the EF Team :

EDM, the underlying meta-model used by the EF6 runtime to reason about the entity types does not support generics. We allow non-generic entity types that inherit from common generic types to be added to models but as we walk up the inheritance hierarchies we stop looking as soon as we hit a generic ancestor. You typically use this capability to model the shape of your entity types using the full expressiveness of inheritance and generics while on the CLR side of things, however on the EF side this results in unrelated entity types being added.

That way you have defined your DbContext, from the perspective of the EF6 runtime you are adding three different and unrelated entity types: AbstractBase, Concrete1 and Concrete2. All the generic types in the middle of the hierarchy have been ignored and therefore EF does not know that they are related.

With that limitation in mind, the exception you are getting is expected, since AbstractBase is abstract and does not have any concrete descendants know to EF. If you add a separate non-generic and concrete type that inherits directly from AbstractBase, e.g.:

public class ConcreteFork : AbstractBase {  }

Your model should be valid again. However you won't be able to use MyContext.AbstractBases to bootstrap queries that return instances of Concrete1 or Concrete2, as EF is unaware of the fact that they are related.

By the way, in EF7 we got rid of the EDM layer for the implementation of EF and we expect to be able to support more and more scenarios for actual generic entity types.

Hope this helps explain what is going on.

Diego

like image 50
tobiak777 Avatar answered Nov 15 '22 13:11

tobiak777