What does principal end of an association means in 1:1 relationship in Entity framework
In one-to-one relation one end must be principal and second end must be dependent. Principal end is the one which will be inserted first and which can exist without the dependent one. Dependent end is the one which must be inserted after the principal because it has foreign key to the principal.
In case of entity framework FK in dependent must also be its PK so in your case you should use:
public class Boo
{
[Key, ForeignKey("Foo")]
public string BooId{get;set;}
public Foo Foo{get;set;}
}
Or fluent mapping
modelBuilder.Entity<Foo>()
.HasOptional(f => f.Boo)
.WithRequired(s => s.Foo);
You can also use the [Required]
data annotation attribute to solve this:
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
is required for Boo
.
This is with reference to @Ladislav Mrnka's answer on using fluent api for configuring one-to-one relationship.
Had a situation where having FK of dependent must be it's PK
was not feasible.
E.g., Foo
already has one-to-many relationship with 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;
}
Now, we had to add another one-to-one relationship between Foo and 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;
}
Here is how to specify one-to-one relationship using fluent api:
modelBuilder.Entity<Bar>()
.HasOptional(p => p.PrimaryBarOfFoo)
.WithOptionalPrincipal(o => o.PrimaryBar)
.Map(x => x.MapKey("PrimaryBarId"));
Note that while adding PrimaryBarId
needs to be removed, as we specifying it through fluent api.
Also note that method name [WithOptionalPrincipal()][1]
is kind of ironic. In this case, Principal is Bar. WithOptionalDependent() description on msdn makes it more clear.