6

Ho il seguente requisito che funziona bene nello spazio OO ma non riesco a farlo tornare al DB usando prima il codice EF ADO.Mappatura dell'ereditarietà di classe intermedia ADO EF First

Ho prodotti numerici ognuno avrà aspetti diversi (attributi ma non nel senso di attributi di codice). Per esempio l'anello avrebbe aspetti come il tipo minerale = oro ecc. Mentre un diamante avrebbe un aspec di chiarezza = VVSI1.

Come potete vedere i prodotti molto in grande nella loro composizione e voglio un modo dinamico di far crescere il mio sistema.

Come tale ho creato una classe di prodotto:

public class Product 
{ 
    public int id { get; set; } 
    public string Name { get; set; } 
    private List<ProductAspect> aspects = new List<ProductAspect>(); 
    public List<ProductAspect> Aspects { get { return aspects; } set { aspects = value; } } 
} 

Ha una lista di ProductAspect che è la classe base per tutti gli aspetti di andare avanti:

public class ProductAspect 
{ 
    public int id { get; set; } 
    public string AspectName { get; set; } 
} 

Ho poi ereditare dal ProductAspect utilizzando un generico che mi consente di essere specifico (fortemente digitato) sul mio Aspect Value:

public abstract class ProductAspect<T> : ProductAspect 
{ 
    public T AspectValue { get; set; } 
} 

Ho poi creo alcuni aspetti che mi permetterà di decorare il mio prodotto:

public class StringAspect : ProductAspect<string> { }; 
public class DecimalAspect : ProductAspect<decimal> { }; 
public class ImageAspect : ProductAspect<byte[]> { }; 

Ho poi dare il DbContext una prova e hanno provato entrambe le TPH e TPC mappature di successione.

Nessuno dei due sembra funzionare. Il modello DB che viene generato non crea una chiave foriegn alle tabelle StringAspect o DecimalAspect dalla Tabella aspetto.

public class IxamDataContext : DbContext 
{ 
    public DbSet<Product> Products { get; set; } 
    public DbSet<ProductAspect> Aspects { get; set; } 

    protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     base.OnModelCreating(modelBuilder); 
     AspectMapping(modelBuilder); 
    } 

    private void AspectMapping(DbModelBuilder mb) 
    { 
     //TPH 
     //mb.Entity<ProductAspect>() 
     // .Map<StringAspect>(m => m.Requires("type").HasValue("sa")) 
     // .Map<DecimalAspect>(m => m.Requires("type").HasValue("da")); 

     //TPC 
     //mb.Entity<StringAspect>().ToTable("StringAspect"); 
     //mb.Entity<DecimalAspect>().ToTable("DecimalAspect"); 
    } 
} 

Conseguente la seguente eccezione per questo codice di semina:

 Product p = new Product(); 
     p.Name = "Diamond"; 
     p.Aspects.Add(new StringAspect() { AspectName = "History", AspectValue = "Old and long" }); 
     p.Aspects.Add(new DecimalAspect() { AspectName = "Weight", AspectValue= 96.5M }); 


     context.Products.Add(p); 
     context.SaveChanges(); 

Excpetion:

EntityType 'StringAspect' non esiste in 'IxamDataContext.Aspects' EntitySet . Parametro nome: entità

Qualche idea dal codice EF per i primi professionisti là fuori?

risposta

2

Il framework di entità non supporta i tipi intermedi non mappati nella gerarchia di ereditarietà. Significa che non puoi avere questa ereditarietà: A (mappato) -> B (non mappato) -> C (mappato). EF non supporta anche la mappatura di tipi generici. Significa che è necessario rimuovere la classe intermedia generica dalla gerarchia e spostare AspectValue in tipi derivati ​​con tipo corretto.

+0

Grazie per la risposta. – Hugo

0

Forse è troppo tardi, ma ti offrirei usando ComplexType attribute che ti consentirà di estendere i tuoi tipi come desideri.

Problemi correlati