7

sto usando EntityFramework 5 (o 4.3 per .Net Framework 4.0)EntityFramework anonima composito nome della proprietà chiave di conflitto

Nel mio oggetto DbContext ho già impostato le DbSets corretti e gli oggetti contengono riferimenti adeguati gli uni agli altri. Questo non è nuovo per me, e le cose funzionano bene.

Ora in questo caso ho alcune chiavi composite che, a volte, includono la chiave esterna di una tabella (o oggetto in questo caso). Per questo uso la funzione HasKey<>() nel metodo OnModelCreating di DbContext. Quando queste proprietà hanno nomi diversi, non ci sono problemi, ma quando queste proprietà hanno lo stesso nome, la migrazione non può essere eseguita.

Un esempio:

protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     // ... 

     modelBuilder.Entity<PatientVisit>().ToTable("PatientVisits"); 
     modelBuilder.Entity<PatientVisit>().HasKey(x => 
      new { x.Patient.Code, x.Code }); 

     // ... 

     base.OnModelCreating(modelBuilder); 
    } 

Come si può vedere nel codice fornito, l'PatientVisit oggetto ha una proprietà denominata codice, ma questa proprietà può essere ripetuta fino a quando si ripete con un altro paziente. L'entità Paziente ha anche una chiave definita come Codice.

Un tipo anonimo non può avere due proprietà che deducono lo stesso nome (ovvio). La soluzione tipica potrebbe essere quella di nominare le proprietà del tipo anonimo in questo modo:

protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     // ... 

     modelBuilder.Entity<PatientVisit>().ToTable("PatientVisits"); 
     modelBuilder.Entity<PatientVisit>().HasKey(x => 
      new { PatientCode = x.Patient.Code, VisitCode = x.Code }); 

     // ... 

     base.OnModelCreating(modelBuilder); 
    } 

Ma facendo questo, quando provo ad aggiungere una migrazione è gettato questo messaggio di errore.

The properties expression 'x => new <>f__AnonymousType3`2(PatientCode 
= x.Patient.Code, VisitCode = x.Code)' is not valid. The expression 
should represent a property: C#: 't => t.MyProperty' VB.Net: 'Function(t) 
t.MyProperty'. When specifying multiple properties use an anonymous 
type: C#: 't => new { t.MyProperty1, t.MyProperty2 }' 
VB.Net: 'Function(t) New With { t.MyProperty1, t.MyProperty2 }'. 

risposta

0

Penso che quello che dovete fare è dare PatientVisit una nuova proprietà PatientCode. Quale sarebbe la chiave esterna a Patient. Ad esempio

HasRequired<PatientVisit>(v => v.Patient).WithMany() 
              .HasForeignKey(v => v.PatientCode) 

Poi si può fare

modelBuilder.Entity<PatientVisit>().HasKey(x => 
     new { x.PatientCode, x.Code }); 
+1

So che ci sono soluzioni che richiedono me di aggiungere manualmente le chiavi e gli ID degli oggetti di riferimento, ma che implica "cambiare" un modello semplice oggetto in un database -mapping model, e preferisco non farlo. –

+0

La tua soluzione è simile a quella che ho implementato, solo che non è necessaria alcuna mappatura fluida perché è fatta da DataAnnotations. Fondamentalmente sta usando l'attributo 'ForeignKey' per collegare una proprietà dichiarata alla chiave esterna di una proprietà di navigazione virtuale ... ma implica comunque che _i debba definire esplicitamente_ le proprietà di navigazione _e_ le proprietà di ancoraggio o chiave esterna. Mi piacerebbe avere un modello di oggetto pulito, pulito, senza proprietà chiave relative al database. –

+0

Per un esempio della soluzione _current-but-not-wanted_ a cui mi riferisco, vedere [questo thread] (http://stackoverflow.com/questions/5388077/primary-foreign-key-in-entity-framework) dove è spiegato molto bene. –