2013-06-22 10 views
13

"Il fine principale di questa associazione deve essere configurato in modo esplicito utilizzando l'API della relazione fluente o le annotazioni dei dati."La fine principale di questa associazione deve essere configurata in modo esplicito utilizzando l'API della relazione fluente o le annotazioni dei dati

Ricevo questo errore in Entity Framework 4.4 durante l'aggiornamento/migrazione del database, ma non sto tentando di specificare una relazione 1: 1. Voglio qualcosa di simile:

public class EntityA 
{ 
    public int ID { get; set; } 
    public int EntityBID { get; set; } 

    [ForeignKey("EntityBID")] 
    public virtual EntityB EntityB { get; set; } 
} 

public class EntityB 
{ 
    public int ID { get; set; } 
    public Nullable<int> PreferredEntityAID { get; set; } 

    [ForeignKey("PreferredEntityAID")] 
    public virtual EntityA PreferredEntityA { get; set; } 
} 

dove EntityA deve avere un genitore EntityB, mentre EntityB può avere un figlio preferito EntityA, ma non deve. Il bambino preferito dovrebbe essere uno dei figli associati al genitore, ma non so come applicarlo nel database. Sto programmando di applicarlo a livello di codice.

Come aggirare questo errore o quale è un modo migliore per realizzare queste relazioni?

+1

'[ForeignKey ("EntityAID") ] 'significa che dovrebbe esserci la proprietà' EntityB.EntityAID'. Ti sei perso in un campione? – Dennis

+1

Intendi [ForeignKey ("PreferredEntityAID")]? – ChaseMedallion

+0

Grazie per aver capito. Mi sono appena perso nel mio esempio. L'ho modificato – lintmouse

risposta

28

Codice quadro entità: le prime convenzioni presuppongono che EntityA.EntityB e EntityB.PreferredEntityA appartengano alla stessa relazione e siano le proprietà di navigazione inversa l'una dell'altra. Poiché entrambe le proprietà di navigazione sono riferimenti (non raccolte) EF deduce una relazione uno-a-uno.

Dal momento che si desidera effettivamente due relazioni uno-a-molti è necessario sovrascrivere le convenzioni. Con il vostro modello è possibile solo con API Fluent:

modelBuilder.Entity<EntityA>() 
    .HasRequired(a => a.EntityB) 
    .WithMany() 
    .HasForeignKey(a => a.EntityBID); 

modelBuilder.Entity<EntityB>() 
    .HasOptional(b => b.PreferredEntityA) 
    .WithMany() 
    .HasForeignKey(b => b.PreferredEntityAID); 

(. Se si utilizza questo è possibile rimuovere gli attributi [ForeignKey])

Non è possibile specificare una mappatura in grado di garantire che il bambino preferito è sempre uno dei i bambini associati.

Se non si desidera utilizzare API perfetto ma solo le annotazioni di dati è possibile aggiungere una proprietà della raccolta in EntityB e si riferiscono alla EntityA.EntityB utilizzando l'attributo [InverseProperty]:

public class EntityB 
{ 
    public int ID { get; set; } 
    public Nullable<int> PreferredEntityAID { get; set; } 

    [ForeignKey("PreferredEntityAID")] 
    public virtual EntityA PreferredEntityA { get; set; } 

    [InverseProperty("EntityB")] // <- Navigation property name in EntityA 
    public virtual ICollection<EntityA> EntityAs { get; set; } 
} 
+2

Questo ha fatto il trucco. Grazie. – lintmouse