Database 如何为a';有一个';多原则的数据库关系?

Database 如何为a';有一个';多原则的数据库关系?,database,entity-framework,database-design,entity-framework-core,Database,Entity Framework,Database Design,Entity Framework Core,在代码中,我有一个如下所示的对象图: 公共类作者 { 公共int AuthorId{get;set;} 公共字符串名称{get;set;} 公共广播地址{get;set;} } 公共类出版商 { public int PublisherId{get;set;} 公共字符串名称{get;set;} 公共广播地址{get;set;} } 公共课堂演讲 { public int AddressId{get;set;} 公共字符串邮政编码{get;set;} } 如何在关系数据库模式中对此进行建模 这

在代码中,我有一个如下所示的对象图:

公共类作者
{
公共int AuthorId{get;set;}
公共字符串名称{get;set;}
公共广播地址{get;set;}
}
公共类出版商
{
public int PublisherId{get;set;}
公共字符串名称{get;set;}
公共广播地址{get;set;}
}
公共课堂演讲
{
public int AddressId{get;set;}
公共字符串邮政编码{get;set;}
}
如何在关系数据库模式中对此进行建模

这需要是0-1..1关系,即作者和发布者可能有地址,也可能没有地址

理想情况下,地址必须由作者或出版商引用,但不能同时由两者引用

如果您可以使用导航属性在Entity Framework Core中对其进行建模,并在删除作者或发布者时让cascade delete删除地址,则将获得巨大的好处。(但我打赌没有人能做到)


我会列出所有我尝试过的东西,但是帖子太长了,没人会看。只要说我已经尝试了我能想到的一切,就会更快

在EF Core中有很多方法可以实现目标。关键的一点是,
地址
将是关系的依赖端,它将包含主要实体
作者
出版商
的可选FK

以下是可能的
地址
型号和配置:

(1)
地址
,具有明确的FK和导航属性

型号:

配置:

配置:

配置:

配置:


modelBuilder.Entity

在EF Core中有很多方法可以实现目标。关键的一点是,
地址
将是关系的依赖端,它将包含主要实体
作者
出版商
的可选FK

以下是可能的
地址
型号和配置:

(1)
地址
,具有明确的FK和导航属性

型号:

配置:

配置:

配置:

配置:


modelBuilder.Entity

我们可以将属性添加到
Address
类中,还是应该保持现在的状态?您可以将属性添加到Address。所有表都可以根据需要进行调整以建立所需的关系。我们可以将属性添加到
Address
类中,还是应该保持现在的状态?您可以将属性添加到Address中。所有的表都可以根据需要进行调整,以建立所需的关系。我认为也可以选择拥有的类型,不是吗?(“可根据需要调整所有表格,以建立所需的关系”)@Gert Sure。但我的理解是,OP明确地想要1到0..1关系(作者和发布者可能有或没有地址),而拥有的类型表示1到1(即必需的)关系,就像EF6复杂类型一样?是的,它是复杂类型的ef核心等价物。但当然这不是可选的,所以我想它不完全符合要求。但对于OP来说,这可能值得考虑,因为它大大简化了数据模型,地址字段是所有者表的一部分。缺点:如果要创建一个实体,则始终必须创建两个实体(
Publisher
Address
等)。但一个小工厂的方法将隐藏这种不便。我想我会去的(但我对多态关联和可空外键有点过敏)。这个答案非常有用。非常感谢。我想也有自己的类型将是一个选择,不是吗?(“可根据需要调整所有表格,以建立所需的关系”)@Gert Sure。但我的理解是,OP明确地想要1到0..1关系(作者和发布者可能有或没有地址),而拥有的类型表示1到1(即必需的)关系,就像EF6复杂类型一样?是的,它是复杂类型的ef核心等价物。但当然这不是可选的,所以我想它不完全符合要求。但对于OP来说,这可能值得考虑,因为它大大简化了数据模型,地址字段是所有者表的一部分。缺点:如果要创建一个实体,则始终必须创建两个实体(
Publisher
Address
等)。但一个小工厂的方法将隐藏这种不便。我想我会去的(但我对多态关联和可空外键有点过敏)。这个答案非常有用。非常感谢。
public class Address
{
    public int AddressId { get; set; }
    public string Postcode { get; set; }

    public int? AuthorId { get; set; }
    public Author Author { get; set; }

    public int? PublisherId { get; set; }
    public Publisher Publisher { get; set; }
}
modelBuilder.Entity<Author>()
    .HasOne(e => e.Address)
    .WithOne(e => e.Author)
    .HasForeignKey<Address>(e => e.AuthorId)
    .OnDelete(DeleteBehavior.Cascade);

modelBuilder.Entity<Publisher>()
    .HasOne(e => e.Address)
    .WithOne(e => e.Publisher)
    .HasForeignKey<Address>(e => e.PublisherId)
    .OnDelete(DeleteBehavior.Cascade);
public class Address
{
    public int AddressId { get; set; }
    public string Postcode { get; set; }

    public Author Author { get; set; }

    public Publisher Publisher { get; set; }
}
modelBuilder.Entity<Author>()
    .HasOne(e => e.Address)
    .WithOne(e => e.Author)
    .HasForeignKey<Address>("AuthorId")
    .OnDelete(DeleteBehavior.Cascade);

modelBuilder.Entity<Publisher>()
    .HasOne(e => e.Address)
    .WithOne(e => e.Publisher)
    .HasForeignKey<Address>("PublisherId")
    .OnDelete(DeleteBehavior.Cascade);
public class Address
{
    public int AddressId { get; set; }
    public string Postcode { get; set; }

    public int? AuthorId { get; set; }

    public int? PublisherId { get; set; }
}
modelBuilder.Entity<Author>()
    .HasOne(e => e.Address)
    .WithOne()
    .HasForeignKey<Address>(e => e.AuthorId)
    .OnDelete(DeleteBehavior.Cascade);

modelBuilder.Entity<Publisher>()
    .HasOne(e => e.Address)
    .WithOne()
    .HasForeignKey<Address>(e => e.PublisherId)
    .OnDelete(DeleteBehavior.Cascade);
public class Address
{
    public int AddressId { get; set; }
    public string Postcode { get; set; }
}
modelBuilder.Entity<Author>()
    .HasOne(e => e.Address)
    .WithOne()
    .HasForeignKey<Address>("AuthorId")
    .OnDelete(DeleteBehavior.Cascade);

modelBuilder.Entity<Publisher>()
    .HasOne(e => e.Address)
    .WithOne()
    .HasForeignKey<Address>("PublisherId")
    .OnDelete(DeleteBehavior.Cascade);