Sto riscontrando un problema con il collegamento di due tabelle in FluentAPI. In realtà è un mix di FluentAPI e Annotazioni dei dati. Ho guardato questa domanda ma non mi ha aiutato. Ho provato con Index
, composto tasti unici.
Fondamentalmente Foo
è il tavolo principale. Bar
tavolo Bar
è opzionale. Sono collegati tramite due colonne. key1
coppie key1
e key2
sono uniche. Consideralo come una relazione genitore-figlio con una limitazione secondo cui 1 genitore può avere solo 1 figlio:
Le entità dati si presentano così:
[Table("foo")]
public class Foo
{
[Key]
[Column("pk", TypeName = "int")]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int FooId { get; set; }
[Column("key1", TypeName = "int")]
public int Key1 { get; set; }
[Column("key2", TypeName = "int")]
public int Key2 { get; set; }
public Bar Bar { get; set; }
}
[Table("bar")]
public class Bar
{
[Key]
[Column("key1", TypeName = "int", Order = 1)]
public int Key1 { get; set; }
[Key]
[Column("key2", TypeName = "int", Order = 2)]
public int Key2 { get; set; }
public Foo Foo { get; set; }
}
Ecco come stavo cercando di collegarli:
modelBuilder.Entity<Bar>().HasRequired(p => p.Foo).WithOptional(p => p.Bar);
Che c'è? Bar
richiede Foo
. Foo
ha una Bar
opzionale. <--- questo dovrebbe essere abbastanza, perché Foo
ha colonne identificate esattamente come le chiavi primarie in Bar
. Ma non funziona.
Così ho provato a specificare le chiavi esterne:
modelBuilder.Entity<Bar>().HasRequired(p => p.Foo).WithOptional(p => p.Bar).Map(p => p.MapKey(new[] { "key1", "key2" }));
Dice:
"Il numero di colonne specificato deve corrispondere al numero di colonne chiave primarie"
Whaaaat? Come? come mai? Uhh ..
Ho anche provato:
modelBuilder.Entity<Bar>().HasIndex(table => new { table.Key1, table.Key2 });
Quindi le mie domande sono:
Perché la mia soluzione non funziona? Ho specificato una chiave complessa
Come posso farlo?
Questo sarà un po 'complicato, e potrei sbagliarmi completamente qui, ma dalla mia esperienza le relazioni EntityFramework non funzionano in questo modo. Mi sembra che se Foo è richiesto e Bar è opzionale , allora ogni Barra dovrebbe avere un modo per unirsi a Foo in modo univoco basato sul valore di pk di Foo.
Ciò significa che la barra dovrebbe essere definita come:
[Table("bar")]
public class Bar
{
[Key]
[Column("key1", TypeName = "int", Order = 1)]
public int Key1 { get; set; }
[Key]
[Column("key2", TypeName = "int", Order = 2)]
public int Key2 { get; set; }
public int FooId { get; set; }
public Foo Foo { get; set; }
}
Dovresti quindi usare questo FooId nella descrizione della relazione, non nella chiave composita contenuta in Bar. EntityFramework mi ha sempre richiesto di unirmi all'intera chiave primaria del padre POCO, che deve essere una chiave esterna del POCO figlio. Potresti ancora essere in grado di unirti tramite la chiave del bambino nelle query LINQ.