实体框架中一个关联的主体端在1:1关系中意味着什么
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;} }
当我遇到错误时,我试图在Entity Framework中做到这一点:
无法确定类型“ConsoleApplication5.Boo”和“ConsoleApplication5.Foo”之间关联的主要结尾。 此关联的主要目的必须使用关系流畅API或数据注释来显式配置。
我已经在StackOverflow上看到了有关此错误的解决方案的问题,但我想了解术语“主体端”的含义。
在一对一关系中,一端必须是主体,第二端必须是依赖的。 主要目的是先插入,不存在依赖关系。 由于委托人有外键,所以委托人必须插入委托人。
在实体框架FK in dependent也必须是它的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);
你也可以使用[Required]
数据注解属性来解决这个问题:
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; } }
Boo
需要Foo
。
这是参考@Ladislav Mrnka的使用流利的API配置一对一的关系的答案。
有一个情况,有相关的FK of dependent must be it's 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; pubic 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; }
以下是如何使用流利的api指定一对一的关系:
modelBuilder.Entity<Bar>() .HasOptional(p => p.PrimaryBarOfFoo) .WithOptionalPrincipal(o => o.PrimaryBar) .Map(x => x.MapKey("PrimaryBarId"));
请注意,虽然添加PrimaryBarId
需要删除,因为我们通过流利的API指定它。
还要注意,方法名[WithOptionalPrincipal()][1]
有点讽刺意味。 在这种情况下,Principal是Bar。 WithOptionalDependent()对msdn的描述使得它更清晰。