Se si dispone di più di una proprietà di navigazione riferendosi alla stessa entità EF non sa dove la proprietà di navigazione inversa sul altra entità appartiene. Nel tuo esempio: A.ObjectsOfB
si riferisce a B.ObjectA
o a B.OtherObjectsOfA
? Entrambi sarebbero possibili e un modello valido.
Ora, EF non genera un'eccezione del tipo "non può determinare le relazioni in modo inequivocabile", o qualcosa del genere. Decide invece che B.ObjectA
fa riferimento a un terzo endpoint in B
che non è esposto come proprietà di navigazione nel modello. Ciò crea la prima chiave esterna nella tabella B
. Le due proprietà di navigazione in B
si riferiscono a due endpoint in A
che non sono esposti nel modello: B.ObjectA
crea la seconda chiave esterna nella tabella B
e B.OtherObjectsOfA
crea una chiave esterna nella tabella A
.
Per risolvere questo problema è necessario specificare le relazioni in modo esplicito.
Opzione uno (il modo più semplice) è quello di utilizzare l'attributo InverseProperty
:
public class A
{
public int Id { get; set; }
public string Name { get; set; }
[InverseProperty("OtherObjectsOfA")]
public virtual ICollection<B> ObjectsOfB { get; set; }
}
Definisce che A.ObjectsOfB
fa parte di un molti-a-molti relazione B.OtherObjectsOfA
.
L'altra opzione è quella di definire completamente le relazioni in API Fluent:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<A>()
.HasMany(a => a.ObjectsOfB)
.WithMany(b => b.OtherObjectsOfA)
.Map(x =>
{
x.MapLeftKey("AId");
x.MapRightKey("BId");
x.ToTable("ABs");
});
modelBuilder.Entity<B>()
.HasRequired(b => b.ObjectA) // or HasOptional
.WithMany()
.WillCascadeOnDelete(false); // not sure if necessary, you can try it
// without if you want cascading delete
}
Grazie per la tua risposta! Tuttavia, per entrambe le soluzioni ottengo la seguente eccezione: 'Si è verificata una prima eccezione di tipo 'System.InvalidOperationException' in EntityFramework.DLL' – Marthijn
Correzione: la soluzione fluente funziona (errore mio ..), quindi grazie per questo! Qualche idea sul perché "InverseProperty' generi un'eccezione? – Marthijn
@Henkie: l'applicazione si blocca davvero? "La prima eccezione casuale" di solito non è un problema e viene mostrata solo nella finestra di output del debugger. Normalmente può essere ignorato. – Slauma