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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With