2016-01-28 14 views
6

Sto utilizzando EF 6 e utilizzo una strategia TPT per modellare il mio problema. Rule è una classe astratta. OvertimeRule è una classe concreta, che eredita da Rule.EF e TPT: il nome della colonna è specificato più di una volta nella clausola SET

Rule assomiglia a questo:

public abstract class Rule 
{ 
    public int Id { get; set; } 
    public PeriodType PeriodType { get; set; } 
    public int SortOrder { get; set; } 
    public int StatuteId { get; set; } 
    public bool IsActive { get; set; } 
} 

OvertimeRule assomiglia a questo:

public partial class OvertimeRule : Rule 
{ 
    public decimal? ThresholdCoefficient { get; set; } 
    public decimal? LimitCoefficient { get; set; } 
} 

Quando creo un nuovo OvertimeRule e cercare di salvarlo, EF genera prima questa query:

INSERT [dbo].[Rules]([PeriodType], [SortOrder], [StatuteId], [IsActive], [StatuteID]) 
VALUES (@0, @1, @2, @3, @4, @5, @6, NULL) 

Come potete vedere, EF aggiunge unoColonnaall'inserto, che non esiste da nessuna parte nella soluzione e rende questa una query SQL non valida.

SQL poi getta giustamente: The column name 'StatuteId' is specified more than once in the SET clause. A column cannot be assigned more than one value in the same SET clause. Modify the SET clause to make sure that a column is updated only once. If the SET clause updates columns of a view, then the column name 'StatuteId' may appear twice in the view definition.

La mappatura si presenta così:

 modelBuilder.Entity<Rule>().ToTable("Rules", TimmiSchemaName); 
     modelBuilder.Entity<Rule>().HasRequired(s => s.Statute).WithMany(s => s.Rules).HasForeignKey(r => r.StatuteId); 
     modelBuilder.Entity<OvertimeRule>().ToTable("OverTimeRules", TimmiSchemaName); 

Qualcuno potrebbe dirmi che cosa potrebbe innescare questo comportamento?

+0

Mostra la tua definizione OvertimeRule prega – tede24

+0

fatto. Niente di interessante da vedere davvero qui .. –

risposta

1

Questo era difficile.

modelBuilder.Entity<Rule>().HasRequired(s => s.Statute).WithMany().HasForeignKey(r => r.StatuteId); 

è in realtà errata, e avrebbe dovuto essere

modelBuilder.Entity<Rule>().HasRequired(s => s.Statute).WithMany(s => s.Rules).HasForeignKey(r => r.StatuteId); 

come la proprietà statute.Rules esisteva dall'altra parte della chiave esterna.

Senza esso, EF tenta di associare automaticamente la proprietà a una colonna sql dalla tabella Regole, che ha indovinato dovrebbe essere StatuteID.

+0

Modifica il tuo post invece per favore, le risposte sono per le risposte –

+1

Sono abbastanza sicuro di aver seguito le linee guida qui http://stackoverflow.com/help/self-answer –

+1

Oh non lo sapevo risolto il tuo problema, il mio male –

1

vedo due cose strane nel codice che hai fornito:

1)

modelBuilder.Entity<Rule>().HasRequired(s => s.Statute)... 

Questa parte spiega la proprietà Statute è richiesto in Rule, tuttavia è in nessun posto essere visti. Come si compila anche questo?

2)

modelBuilder.Entity<Rule>().ToTable("Rules", TimmiSchemaName); 

Il punto di TPT è che si utilizza uno dei vostri tavoli come una classe astratta che significa che sarà utilizzare tale tabella per i modelli che ne derivano. Non dovresti essere in grado di recuperare una Regola, ma puoi recuperare un OverTimeRule quale è una Regola. È inoltre importante che la chiave primaria delle tabelle derivate sia esattamente la stessa chiave primaria della tabella di base.La classe contesto dovrebbe essere simile a questo:

public class MyContext : DbContext 
{ 
    public DbSet<Rule> Rules {get; set;} 

    protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     modelBuilder.Entity<OverTimeRule>().ToTable("OverTimeRules"); 
     ... 
    } 
} 

Davvero grande articolo qui: http://weblogs.asp.net/manavi/inheritance-mapping-strategies-with-entity-framework-code-first-ctp5-part-2-table-per-type-tpt

+0

1: non l'ho menzionato nella domanda, ma esiste davvero. 2: stai dicendo che modelBuilder.Entity () .ToTable ("Rules", TimmiSchemaName); 'è inutile? Perché altrimenti, rispetto ciò che l'articolo suggerisce :) –

+0

Infatti, probabilmente non genererà eccezioni o nulla se ce l'hai, ma per TPT non dovrebbe essere definito. –

Problemi correlati