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

时间:2017-08-19 14:29:14

标签: asp.net-mvc database entity-framework asp.net-mvc-5 ef-fluent-api

我是初学者,从教程中学习流利的API。我读了一些已经给出的关于 1-0,1 - * 的SO解决方案,但我无法理解它们。我只想使用流畅的API 来设置一对一和一对零关系,但不遵循惯例。

House and Room(可怕的例子)

要求:

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; }
}

所以,房间不能没有房子,但房子可以不存在房间。此外,如果房子有房间,它只能有一个。

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

我看到了一些解决方案,但是他们正在设置PK and FK same。但我想要这样做。有没有办法实现我想要的没有设置PK和FK相同。我不希望HouseID成为我的Room类的PK。在我的情况下,校长是House和Dependent是Room。我是否需要添加像"Optional Dependent" or "Optional Principal"这样的东西。有人可以指导我,我是初学者。

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

如何告诉EF使用Room类的HouseId作为FK。

1 个答案:

答案 0 :(得分:1)

  

同样在我的案例中,校长是House and Dependent is Room

然后你走在正确的轨道上

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

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

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

删除该属性:

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

并使用Map流畅的API和MapKey来指定FK列名称:

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

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