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;}
}
当我得到错误时,我试图在实体框架中这样做:
无法确定类型之间关联的主端
“ConsoleApplication5。Boo'和'ConsoleApplication5.Foo'
属性显式配置此关联的主体端
关系流畅API或数据注释。
我在StackOverflow上看到了这个错误的解决方案,但我想了解术语“principal end”是什么意思。
在一对一的关系中,一端必须是主的,另一端必须是从属的。主端是最先插入的端,并且可以在没有从属端的情况下存在。依赖端必须插入到主体之后,因为它有指向主体的外键。
在实体框架的情况下,依赖的FK也必须是它的PK,所以在你的情况下,你应该使用:
public class Boo
{
[Key, ForeignKey("Foo")]
public string BooId{get;set;}
public Foo Foo{get;set;}
}
或者流畅映射
modelBuilder.Entity<Foo>()
.HasOptional(f => f.Boo)
.WithRequired(s => s.Foo);
这是参考@Ladislav Mrnka关于使用fluent api配置一对一关系的回答。
有一种情况,依赖的FK必须是它的PK是不可行的。
例如,Foo已经和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;
}
现在,我们必须在Foo和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;
}
下面是如何使用fluent api指定一对一的关系:
modelBuilder.Entity<Bar>()
.HasOptional(p => p.PrimaryBarOfFoo)
.WithOptionalPrincipal(o => o.PrimaryBar)
.Map(x => x.MapKey("PrimaryBarId"));
请注意,在添加PrimaryBarId时需要删除,因为我们通过fluent api指定它。
还要注意方法名[WithOptionalPrincipal()][1]有点讽刺。在本例中,Principal是Bar。msdn上的WithOptionalDependent()描述使其更加清晰。