Domanda

Sto utilizzando il codice Entity Framework 4 CTP5 primo approccio e ho una tabella per ogni gerarchia (TPH) mappatura. Alcune delle mie classi nella gerarchia hanno proprietà in comune.

public class BaseType
{
    public int Id { get; set; }
}

public class A : BaseType
{
    public string Customer { get; set; }
    public string Order { get; set; }
}

public class B : BaseType
{
    public string Customer { get; set; }
    public string Article { get; set; }
}

public class C : BaseType
{
    public string Article { get; set; }
    public string Manufacturer { get; set; }
}

La convenzione di default associa questo per le seguenti colonne:

  • Id
  • Articolo 1
  • Articolo 2
  • Customer1
  • Customer2
  • Produttore
  • Ordine
  • Tipo

Voglio avere EF4 quota le proprietà comuni a finire con il seguente:

  • Id
  • Articolo
  • Clienti
  • Produttore
  • Ordine
  • Tipo

A parte il ridotto numero di colonne, questo ha il vantaggio di essere in grado di cercare i record in base all'articolo per esempio, senza dover conoscere quali tipi hanno esattamente una proprietà articolo.

Ho provato a mappare ogni proprietà comune alla stessa colonna:

modelBuilder.Entity<B>().Property(n => n.Article).HasColumnName("Article");
modelBuilder.Entity<C>().Property(n => n.Article).HasColumnName("Article");

, ma questo ha gettato la seguente eccezione:

  

schema specificato non è valido. Errori: (36,6): l'errore 0019: ogni nome di proprietà in un tipo devono essere univoci. Nome proprietà 'articolo' è già stato definito.

Qualcuno sa come aggirare questa regola di convalida?

È stato utile?

Soluzione

Non v'è alcuna soluzione per bypassare questa convalida. In TPH una colonna è o appartiene alla classe di base, che è ereditato da tutti bambino o è specializzato per la classe figlia. Non è possibile indicare EF per mappare a due dei vostro bambino, ma non per gli altri. Il tentativo di farlo (ad esempio mettendo [Column(Name = "Customer")] sia A.Customer e B.Customer) sarà causa un MetadataException con questo messaggio:

  

schema specificato non è valido. Errori:   (10,6): l'errore 0019: ogni nome di proprietà in un tipo deve essere univoco. Nome proprietà 'cliente' è stato già definito.

TPH Soluzione:

Una soluzione a questo sarebbe quella di promuovere la Customer e Article proprietà alla classe di base:

public class BaseType {
    public int Id { get; set; }
    public string Customer { get; set; }
    public string Article { get; set; }
}

public class A : BaseType {
    public string Order { get; set; }
}

public class B : BaseType { }

public class C : BaseType {
    public string Manufacturer { get; set; }
}

Quali risultati allo schema desiderato:

alt text

TPT Solution (consigliato):

Detto questo, vi consiglio di considerare l'utilizzo di Tabella per ogni tipo (TPT) dal momento che è una migliore vestibilità per lo scenario:

public class BaseType
{
    public int Id { get; set; }
}

public class A : BaseType
{
    [Column(Name = "Customer")]
    public string Customer { get; set; }
    public string Order { get; set; }
}

public class B : BaseType
{
    [Column(Name = "Customer")]
    public string Customer { get; set; }

    [Column(Name = "Article")]
    public string Article { get; set; }
}

public class C : BaseType
{
    [Column(Name="Article")]
    public string Article { get; set; }
    public string Manufacturer { get; set; }
}

public class MyContext : DbContext
{
    public DbSet<BaseType> BaseTypes { get; set; }        

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<BaseType>().ToTable("BaseType");
        modelBuilder.Entity<A>().ToTable("A");
        modelBuilder.Entity<C>().ToTable("C");
        modelBuilder.Entity<B>().ToTable("B");          
    }
}

alt text

Altri suggerimenti

Per chi stava avendo problemi con questo problema, è stato risolto in EF6: quadro Entity - Codeplex

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top