如何在流利的 api 中配置不同 PK 和 FK 的一对零和一对一关系

How to configure one to zero and one to one relationship in fluent api with different PK and FK

我是初学者,通过教程可以流利地学习 API。我阅读了一些已经给出的关于 1-0, 1-* 的 SO 解决方案,但我无法正确理解它们。我只是想使用 fluent API 来建立 一对一和一对零 关系,前提是没有遵循约定。

房子和房间(糟糕的例子)

要求:

1. One House can have zero room or ONE room MAX.
2. One Room must be inside a house.
3. If a room is deleted House SHOULD NOT Get Deleted
4. If a House is getting deleted and there is a room then
  User should first delete the room then only House should be allowed to be deleted.


public class House
{
    public int HouseId { get; set; }
    public string HouseName { get; set; }
    public virtual Room Room { get; set; }
}

public class Room
{
    public int RoomId { get; set; }
    public string RoomName { get; set; }
    public int HouseId { get; set; }
    public virtual House House { get; set; }
}

因此,房间不能存在 w/o 房子,但房子可以存在 w/o 房间。另外,如果一个房子有房间,它只能有一个。

         dBModelBuilder.Entity<House>()
            .HasOptional(f => f.Room)
            .WithRequired(s => s.House);

我看到了一些解决方案,但他们告诉我要设置 PK and FK same。但我不想那样做。有没有办法实现我想要的 w/o 设置 PK 和 FK 相同。我不想让 HouseID 成为我房间的 PK class。同样在我的例子中,校长是房子,从属是房间。我需要添加 "Optional Dependent" or "Optional Principal" 之类的东西吗?有人可以指导我吗我是初学者。

此外,我是否需要从我的任何模型中删除导航 属性?那是无关紧要的吗?

如何告诉 EF 使用房间 class 的 HouseId 作为 FK。

Also in my case principal is House and Dependent is Room

那么你就在正确的轨道上

modelBuilder.Entity<House>()
    .HasOptional(f => f.Room)
    .WithRequired(s => s.House)

因为在 EF 一对一关系中,需要的一方始终是主体。 principal/dependent 只有当双方都需要或双方都可选时才需要指定。

问题是您要求在依赖实体中使用不同于 PK 的 FK,这是这种关系的默认 EF 模型(所谓的 Shared Primary Key Association),并且得到很好的支持。另一方面,支持一对一的 FK 关联,但有一些限制。更具体地说,不支持 explcit FK 属性 like HouseId in your Room - 没有 HasForeignKey fluent 方法用于此类配置,这是有目的的。我不能说为什么,但这是事实。如果你尝试使用 [ForeignKey] 属性,你会得到意想不到的结果,所以不要那样做。

删除 属性:

public class Room
{
    public int RoomId { get; set; }
    public string RoomName { get; set; }
    public virtual House House { get; set; }
}

并使用 Map fluent API 和 MapKey 来指定 FK 列名称:

modelBuilder.Entity<House>()
    .HasOptional(f => f.Room)
    .WithRequired(s => s.House)
    .Map(c => c.MapKey("HouseId"));

这将为您提供所需的数据库 table 设计(尽管无法将 HouseId 列限制为唯一,除非手动编辑迁移)。