2015-03-22 8 views
8

Ho il seguente modello:L'abstract tipo X non ha discendenti mappati e quindi non può essere mappato

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> { } 

Ma Entity Framework mi dà l'errore:

Il tipo AbstractBase astratto non ha mappato discendenti e quindi non possono essere mappati

A mio parere ciò non dovrebbe accadere poiché AbstractBase eredita direttamente da AbstractBase e dalle classi Concrete1/2 che sono concreti ereditati da GenericAbstractBase. Cosa sta succedendo qui ?

Inoltre, solo per curiosità, mi chiedo se la proprietà di tipo T in GenericAbstractBase venga mantenuta da EF, nel caso in cui qualcuno che passa abbia la risposta in mente.

Update 1

qualcuno può confermare che questo è supportato da EF? Ho visto questo post e secondo la risposta di Rowan questo dovrebbe essere il caso. Grazie

Update 2 stesso problema quando la classe base generica non è astratta.

+0

sono '' Concrete1' e Concrete2' effettivamente mappato nella configurazione? –

+0

Sì, ho DbSets per questi tipi e anch'io li ho registrati esplicitamente in OnModelCreating – reddy

+0

Penso che questo potrebbe essere un duplicato di http://stackoverflow.com/questions/12538004/entity-framework-5-the-abstract -type-x-has-no-mapped-descendents-and-so-cann –

risposta

5

ecco la risposta from the EF Team:

EDM, il meta-modello sottostante utilizzato dal runtime EF6 di ragionare sulle i tipi di entità non supporta farmaci generici. Permettiamo tipi di entità non generici che ereditano da tipi generici comuni da aggiungere ai modelli ma non appena avremo raggiunto le gerarchie di ereditarietà smetteremo di cercare non appena avremo colpito un antenato generico. In genere si utilizza questa capacità di per modellare la forma dei tipi di entità utilizzando l'espressività completa di ereditarietà e generici mentre sul lato CLR di cose, tuttavia sul lato EF ciò comporta l'aggiunta di tipi di entità indipendenti .

In questo modo è stato definito il vostro DbContext, dal punto di vista del runtime EF6 si sta aggiungendo tre diverse e non correlate tipi di entità: AbstractBase, calcestruzzo1 e Concrete2. Tutti i tipi generici nel livello della gerarchia sono stati ignorati e pertanto l'EF non è sa che sono correlati.

Con questa limitazione in mente, l'eccezione che si ottiene è prevista, dal momento che AbstractBase è astratto e non ha alcun discendente concreto conosciuto con EF. Se si aggiunge un tipo concreto riservato ai non generica e che eredita direttamente da AbstractBase, ad es .:

public class ConcreteFork : AbstractBase { } 

Il modello dovrebbe essere di nuovo valida. Tuttavia non sarà possibile utilizzare MyContext.AbstractBases per eseguire il bootstrap di query che restituiscono istanze di Concrete1 o Concrete2, poiché EF non è a conoscenza del fatto che sono correlate a .

A proposito, in EF7 ci siamo sbarazzati dello strato di EDM per l'attuazione di EF e ci aspettiamo di essere in grado di supportare più e più scenari per tipi effettivi di entità generici.

Spero che questo aiuti a spiegare cosa sta succedendo.

Diego

-1

ho trovato la soluzione fornita da Gil Fink nell'articolo CodeProject, Spreading Inheritance Tree Mapping Across Assemblies in Code First.

La soluzione al problema è aggiungere la mappatura a tutte le entità nel contesto. Per fare questo, si dovrà eseguire l'override del metodo OnModelCreating e mappare tutte le entità:

protected override void OnModelCreating(DbModelBuilder modelBuilder) 
{ 
    base.OnModelCreating(modelBuilder); 
    modelBuilder.Entity<AbstractBase>(); 
    modelBuilder.Entity<Concrete1>(); 
    modelBuilder.Entity<Concrete2>(); 
} 
Problemi correlati