¿Qué significa el final principal de una asociación en una relación 1: 1 en el marco de la Entidad?

public class Foo { public string FooId{get;set;} public Boo Boo{get;set;} } public class Boo { public string BooId{get;set;} public Foo Foo{get;set;} } 

Intentaba hacer esto en Entity Framework cuando recibí el error:

No se puede determinar el final principal de una asociación entre los tipos ‘ConsoleApplication5.Boo’ y ‘ConsoleApplication5.Foo’. El extremo principal de esta asociación debe configurarse explícitamente utilizando la relación API o anotaciones de datos con fluidez.

He visto preguntas sobre StackOverflow con una solución para este error, pero quiero entender qué significa el término “final principal”.

En la relación uno-a-uno, un extremo debe ser principal y el segundo extremo debe ser dependiente. El extremo principal es el que se insertará primero y que puede existir sin el dependiente. El extremo dependiente es el que debe insertarse después del principal porque tiene una clave externa para el principal.

En el caso de entity framework FK en dependiente también debe ser su PK por lo que en su caso debe utilizar:

 public class Boo { [Key, ForeignKey("Foo")] public string BooId{get;set;} public Foo Foo{get;set;} } 

O mapeo fluido

 modelBuilder.Entity() .HasOptional(f => f.Boo) .WithRequired(s => s.Foo); 

También puede usar el atributo de anotación de datos [Required] para resolver esto:

 public class Foo { public string FooId { get; set; } public Boo Boo { get; set; } } public class Boo { public string BooId { get; set; } [Required] public Foo Foo {get; set; } } 

Foo es requerido para Boo .

Esto es con referencia a la respuesta de @Ladislav Mrnka sobre el uso de una API apta para configurar una relación uno-a-uno.

Tenía una situación en la que tener FK of dependent must be it's PK no era factible.

Por ejemplo, Foo ya tiene una relación uno a muchos con Bar .

 public class Foo { public Guid FooId; public virtual ICollection<> Bars; } public class Bar { //PK public Guid BarId; //FK to Foo public Guid FooId; public virtual Foo Foo; } 

Ahora, tuvimos que agregar otra relación uno-a-uno entre Foo y Bar.

 public class Foo { public Guid FooId; public Guid PrimaryBarId;// needs to be removed(from entity),as we specify it in fluent api public virtual Bar PrimaryBar; public virtual ICollection<> Bars; } public class Bar { public Guid BarId; public Guid FooId; public virtual Foo PrimaryBarOfFoo; public virtual Foo Foo; } 

A continuación se detalla cómo especificar una relación uno a uno usando una API apta:

 modelBuilder.Entity() .HasOptional(p => p.PrimaryBarOfFoo) .WithOptionalPrincipal(o => o.PrimaryBar) .Map(x => x.MapKey("PrimaryBarId")); 

Tenga en cuenta que al agregar PrimaryBarId debe eliminarse, como lo especificamos mediante una API apta.

También tenga en cuenta que el nombre del método [WithOptionalPrincipal()][1] es un poco irónico. En este caso, Principal es Bar. La descripción WithOptionalDependent () en msdn lo hace más claro.

Intereting Posts