有没有办法在Entity Framework中创建一对一或多关系?我已经看到很多示例显示1到0 .. *的关系,但我想确保在给定的示例中Foo只有在至少有一个Bar的情况下才能存在。
class Foo
{
List<Bar> Bars { get; set; }
}
class Bar
{
public Foo Foo { get; set; }
}
我发现SQL不容易实现这一点,因为我想在Foo表而不是Bar表中使用NOT NULL
,但实体框架可以处理吗?
我意识到我问了一个错误的问题,因为我实际上正在寻找0..1到1 .. *的关系,这是显着不同的。 This是我想问的问题。
答案 0 :(得分:1)
在我所知道的任何SQL数据库中都不可能拥有真正的1对1关系。虽然Set理论允许1比1,但实际上,这很难实现。
这基本上是鸡蛋和鸡蛋的情况。您无法创建Foo,因为您没有Bar,并且您无法创建Bar,因为还没有Foo。创建1到1所需的约束基本上阻止您插入任何实际的行。
现在,您可以禁用约束,插入数据然后重新启用它们,但这是一个真正破坏了限制的目的的hacky kludge。
所以只需接受1到0 .. *并继续前进。
答案 1 :(得分:0)
以下示例讨论了实施此类解决方案的难度和可能性。
映射一对一
一对一映射(当需要双方时)也是一件棘手的事情。
让我们想象一下如何使用外键来表示这一点。同样,CarId
中的People
引用CarId
中的Car
,以及引用PersonId
PersonId
的{{1}} People
PersonId
1}}。
现在如果要插入汽车记录会怎样?为了使此成功,此车记录中必须指定PersonId
,因为它是必需的。要使此People
有效,CarId
中的相应记录必须存在。好的,所以让我们继续插入人事记录。但要成功,有效public class CarEntityTypeConfiguration : EntityTypeConfiguration<Car>
{
public CarEntityTypeConfiguration()
{
this.HasRequired(c => c.Person).WithRequiredDependent(p => p.Car);
this.HasKey(c => c.PersonId);
}
}
必须在人员记录中 - 但该车尚未插入!它不可能,因为我们必须先插入推荐的人员记录。但是我们不能插入引用的人员记录,因为它引用了汽车记录,所以必须先插入(外键 - ):)。
所以这不能代表“逻辑”。方式。同样,你必须删除一个外键。你放弃哪一个取决于你。留有外键的一方称为“依赖”,没有外键的一方称为“&#39; principal&#39;”。同样,为了确保依赖项的唯一性,PK必须是FK,因此不支持添加FK列并将其导入模型。
所以这是配置:
public class PersonEntityTypeConfiguration : EntityTypeConfiguration<Person>
{
public PersonEntityTypeConfiguration()
{
this.HasRequired(p => p.Car).WithRequiredPrincipal(c => c.Person);
}
}
到现在为止你真的应该已经掌握了它的逻辑:)请记住你也可以选择另一面,只需要小心使用WithRequired的Dependent / Principal版本(你仍然需要配置PK)汽车)。
min()
如果您检查数据库架构,您会发现它与一对一或零解决方案的情况完全相同。这又是因为这不是由架构强制执行的,而是由EF本身强制执行的。所以再次注意:)
答案 2 :(得分:0)
尽可能接近是这样的:
class Foo
{
List<Bar> Bars { get; set; }
[Required]
public int PrimaryBarId { get; set; }
public Bar PrimaryBar { get; set; }
}
class Bar
{
public Foo Foo { get; set; }
}
但请注意,数据库不会强制执行
aFoo.PrimaryBar.FooId == aFoo.Id
由于循环FK,这种模型很难更新。