由于 virtual 关键字,这发生在 CodeFirst 中。实际上,您正在创建一种关系,其中创建一个项目需要创建另一个项目。但是,virtual 关键字允许延迟实例化,这意味着创建一种类型的对象不会自动创建另一种类型,从而允许外来项上的 Id 为空。这意味着 0..1 关系,但由于每一面都是虚拟的,所以你得到的是 0..0,这是不允许的。
您可以使用 2 种方法来纠正这种情况。
- 从导航属性的一侧或两侧删除虚拟选项,允许使用 0..1 或 1..1 地图。
- 从每个对象的其他实体显式添加外键属性。即在类上
Region
添加一个属性,FactoryId
并在Factory
添加一个属性RegionId
还有其他方法可以帮助 Entity Framework 确定哪个对象是 Dependent Object,即使用 Entity Framework Fluent api。
来自MSDN
配置两端都需要的关系(一对一)
在大多数情况下,实体框架可以推断出关系中的依赖类型和主体类型。但是,当关系的两端都是必需的或双方都是可选的时,实体框架无法识别依赖者和主体。当关系的两端都需要时,在 HasRequired 方法之后使用 WithRequiredPrincipal 或 WithRequiredDependent。当关系的两端都是可选的时,在 HasOptional 方法之后使用 WithOptionalPrincipal 或 WithOptionalDependent。
以下代码将创建一个 PrincipalFactory
和一个 DependentRegion
// Configure the primary key for the Region
modelBuilder.Entity<Region>()
.HasKey(t => t.RegionId);
modelBuilder.Entity<Factory>()
.HasRequired(t => t.Region)
.WithRequiredPrincipal(t => t.Factory);